module main
struct User {
name string
age int
}
fn (m &User) str() string {
return 'name:${m.name},age:${m.age}'
}
// 联合类型声明
type MySum = User | int | string
fn (ms MySum) str() string {
if ms is int { // 使用is关键字,判断联合类型具体是哪种类型
println('ms type is int')
}
match ms {
// 对接收到的联合类型,使用match语句进行类型判断,每个match分支的ms变量都会被自动造型为分支中对应的类型
int { return ms.str() }
string { return ms }
User { return ms.str() }
}
}
fn add(ms MySum) { // 联合类型作为参数
match ms {
// 可以对接收到的联合类型,使用match语句进行类型判断,每个match分支的ms变量都会被自动造型为分支中对应的类型
int { println('ms is int,value is ${ms}') }
string { println('ms is string,value is ${ms}') }
User { println('ms is User,value is ${ms.str()}') }
}
}
fn sub(i int, s string, u User) MySum { // 联合类型作为返回值
return i
// return s //这个也可以
// return User{name:'tom',age:3} //这个也可以
}
fn main() {
i := 123
s := 'abc'
u := User{
name: 'tom'
age: 33
}
add(i)
add(s)
add(u)
}
获取联合类型的具体类型
联合类型使用内置方法type_name()来返回变量的具体类型。
module main
struct Point {
x int
}
type MySumType = Point | f32 | int
fn main() {
// 联合类型使用type_name()
sa := MySumType(32)
sb := MySumType(f32(123.0))
sc := MySumType(Point{
x: 43
})
println(sa.type_name()) // int
println(sb.type_name()) // f32
println(sc.type_name()) // Point
}
联合类型相等判断
type Str = string | rune
struct Foo {
v int
}
struct Bar {
v int
}
type FooBar = Foo | Bar
fn main() {
s1 := `s`
s2 := `s`
u1 := Str(rune(s1))
u2 := Str(rune(s2))
println( s1 == s1 ) //联合类型判断相等或不等:同类型,同值
println( s1 == s2 )
println( u1 == u1 )
println( u1 == u2 )
//类型不同,值相同也不等
foo := FooBar( Foo{v: 0} )
bar := FooBar( Bar{v: 0} )
println( foo.v == bar.v )
println( foo != bar )
}
for is类型循环判断
用于联合类型的类型循环判断(感觉没啥用,就是一个语法糖而已):
module main
struct Milk {
mut:
name string
}
struct Eggs {
mut:
name string
}
type Food = Eggs | Milk
fn main() {
mut f := Food(Eggs{'test'})
//不带mut
for f is Eggs {
println(typeof(f).name)
break
}
//等价于
for {
if f is Eggs {
println(typeof(f).name)
break
}
}
//带mut
for mut f is Eggs {
f.name = 'eggs'
println(f.name)
break
}
//等价于
for {
if mut f is Eggs {
f.name = 'eggs'
println(f.name)
break
}
}
}
as类型转换
可以通过as将联合类型显式转换为具体的类型,如果转换类型不成功,则报错:V panic: as cast: cannot cast。
module main
type Mysumtype = bool | f64 | int | string
fn main() {
x := Mysumtype(3)
x2 := x as int //联合类型显式转换类型
println(x2)
}
联合类型嵌套
联合类型还可以嵌套使用,支持更复杂的场景:
struct FnDecl {
pos int
}
struct StructDecl {
pos int
}
struct IfExpr {
pos int
}
struct IntegerLiteral {
val string
}
type Expr = IfExpr | IntegerLiteral
type Stmt = FnDecl | StructDecl
type Node = Expr | Stmt //联合类型嵌套
联合类型方法
可以像结构体那样,给联合类型添加方法:
module main
type Mysumtype = int | string
fn main() {
mut m := Mysumtype(11)
m = int(11)
println(m.str())
}
pub fn (mysum Mysumtype) str() string { // 联合类型的方法
return 'from mysumtype'
}