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 = ExistingType
用type
.
可选用?
.
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
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现