V语言08函数类型

type Filter = fn (string) string

type来指示别名.

type Filter = fn (string) string

fn filter(s string, f Filter) string {//f
	return f(s)
}

V有鸭子类型,只要兼容即可,

fn uppercase(s string) string {
	return s.to_upper()
}//然后可用在`过滤`类型处
//显式转为`过滤`类型
my_filter := Filter(uppercase)
//直接也可以,鸭子类型嘛.
my_filter := uppercase

函数可为参数:

println(filter("你好", my_filter))
println(filter("你好", uppercase))//直接
//λ也可以,下面
println(filter("你好世界", fn (s string) string {
	return s.to_upper()
}))

枚举

enum Color {
	red
	green
	blue
}

mut color := Color.red
color = .green//这里省略掉枚举类型
println(color) // "green"
match color {
	.red { println("红") }
	.green { println("绿") }
	.blue { println("蓝") }
}

.用来省略枚举类型.枚举要匹配完或有分支.确保加了新枚字段时,都能够处理到.
枚举不能用保留字,但你可用@来转义.

enum Color {
	@none
	red
	green
	blue
}

color := Color.@none
println(color)
//可用整数赋值
enum Grocery {
	apple
	orange = 5
	pear
}

g1 := int(Grocery.apple)
g2 := int(Grocery.orange)
g3 := int(Grocery.pear)
println("IDs: $g1, $g2, $g3")

要转为,

和类型

就是C++变量.

struct Moon {}

struct Mars {}

struct Venus {}

type World = Mars | Moon | Venus
//C++则是`用 E=变量<A,B,C>`;

sum := World(Moon{})
assert sum.type_name() == "Moon"
println(sum)

type_name返回类型的名字.
和类型,你可以构建递归构,写精确和强大代码.

// V's binary tree
struct Empty {}

struct Node {
	value f64
	left  Tree
	right Tree
}

type Tree = Empty | Node

// 求所有节点和
fn sum(tree Tree) f64 {
	return match tree {
		Empty { 0 }//条件
		Node { tree.value + sum(tree.left) + sum(tree.right) }
	}
}

fn main() {
	left := Node{0.2, Empty{}, Empty{}}
	right := Node{0.3, Empty{}, Node{0.4, Empty{}, Empty{}}}
	tree := Node{0.5, left, right}
	println(sum(tree)) // 0.2 + 0.3 + 0.4 + 0.5 = 1.4
}

判断和类型底层类型用is:sum is Type.转为之一类型:sum as Type.

struct Moon {}

struct Mars {}

struct Venus {}

type World = Mars | Moon | Venus

fn (m Mars) dust_storm() bool {
	return true
}

fn main() {
	mut w := World(Moon{})
	assert w is Moon
	w = Mars{}
	// 用 `as`来访问火星
	mars := w as Mars//不是火星会崩溃
	if mars.dust_storm() {
		println("坏天气")
	}
}

这样,更保险:

if w is Mars {//如果是火星类型.
	assert typeof(w).name == "Mars"
	if w.dust_storm() {
		println("坏天气")
	}
}
if mut w is Mars {//如果是火星类型.
	assert typeof(w).name == "Mars"
	if w.dust_storm() {
		println("坏天气")
	}
}//加个`变`

这是流敏感类型,即在该处其类型不一样,可为父/子类型.如果无警告转换,则是不安全的.其它地方,w为原类型.
匹配决定变量.

struct Moon {}

struct Mars {}

struct Venus {}

type World = Mars | Moon | Venus

fn open_parachutes(n int) {
	println(n)
}

fn land(w World) {//与访问模式差不多.
	match w {
		Moon {} // 无大气
		Mars {
			// 轻
			open_parachutes(3)
		}
		Venus {
			//重
			open_parachutes(1)
		}
	}
}

匹配必须每个子类型匹配到,否则用.

struct Moon {}
struct Mars {}
struct Venus {}

type World = Moon | Mars | Venus

fn (m Moon) moon_walk() {}
fn (m Mars) shiver() {}
fn (v Venus) sweat() {}

fn pass_time(w World) {
    match w {//灵活转换
        //用隐藏变量.
        Moon { w.moon_walk() }
        Mars { w.shiver() }
        else {}
    }
}

类型别名像这样type NewType = ExistingTypetype.
可选用?.

struct User {
	id   int
	name string
}

struct Repo {
	users []User
}

fn (r Repo) find_user_by_id(id int) ?User {
	for user in r.users {
		if user.id == id {
			// V自动包装为可选类型,见返回参数
			return user
		}
	}
	return error("找不到$id类型")
}

fn main() {
	repo := Repo{
		users: [User{1, "李四"}, User{2, "王五"}, User{10, "张三"}]
	}
	user := repo.find_user_by_id(10) or { 
		return
	}//可选类型返回中,必须有个`or`尾巴.
	println(user.id) // "10"
	println(user.name) // "张三"
}

V合并可选/结果为一种类型.函数升级为可选函数,只需要在返回类型前加个?,然后在可能出错的地方,返回错误.不想返回错误,用return none,等价于return error("").
优点是必须处理错误,且代码更简洁.但不用异常块.在块定义错误变量:

user := repo.find_user_by_id(7) or {
	println(err) // 找不到7用户
	return
}
posted @   zjh6  阅读(19)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示