接口

接口定义

使用interface关键字定义接口,跟go一样。

默认是模块级别,使用pub变为公共级别。

接口命名跟结构体一样:要求首字母大写,大驼峰风格。建议以er风格结尾,非强制。

pub interface Speaker {
		speak() string
}

接口方法

结构体实现接口定义的方法时,除了匹配函数签名外,还需要匹配方法接收者是否可变mut:

module main

//接口要求结构体要实现方法为 pub fn (s MyStruct) write(a string) string
pub interface Foo {
	write(string) string
}

//如果加上mut,则表示接口要求 pub fn (mut s MyStruct) write(a string) string
pub interface Bar {
mut:
	write(string) string
}

struct MyStruct {}

pub fn (s MyStruct) write(a string) string {
	return a
}

fn main() {
	s1 := MyStruct{}
	fn1(s1)
}

fn fn1(s Foo) {
	println(s.write('Foo'))
}

fn fn2(s Bar) { //编译不通过
	println(s.write('Foo'))
}

接口字段

接口在其他编程语言中大部分都只能包含方法签名,V语言中接口除了可以包含方法签名,也可以包含字段,虽然包含字段也可以转为方法签名,但是直接约束字段,代码看起来更舒服。

编译时会检查结构体及其组合结构体(子类)是否实现接口字段。

只有字段名,字段类型,是否可变,这三个都跟接口中的字段定义一致,才算实现了这个接口字段。

并且接口字段的命名只能是蛇形命名,而不能使用大写字母。

接口方法

接口也可以像结构体那样有自己的方法,只要结构体实现了接口,就可以调用接口的方法:

接口组合

接口也像结构体那样支持组合,而且支持多重组合:

泛型接口

使用泛型接口可以定义更为通用/泛化的接口。

参考章节:泛型

接口实现

不需要接口实现的关键字,类型无需显示声明所要实现的接口,

鸭子类型:只要结构体实现了接口定义的方法签名,就满足该接口的使用。

0.4.8版本开始,结构体可以有一个可选的关键字implements,用来明确标记结构体实现了哪些接口:

接口可以作为结构体字段类型使用:

空接口类型

可以定义不包含任何接口方法和字段的空接口类型,表示任何类型。

跟go有点不太一样的是不能直接使用interface{}来表示,必须定义一个空接口类型。

获取接口变量的具体类型

接口类型使用内置方法type_name()来返回接口变量的具体类型:

接口变量类型判断及匹配

使用is,!is操作符对接口参数的具体类型进行判断,

使用as操作符对接口参数进行类型转换,

使用match对接口类型参数进行匹配,跟match匹配联合类型一样,每一个分支都会自动造型,非常的好用:

判断类型是否实现接口

判断接口类型是否也实现了其他接口

可以像结构体那样使用is和as来判断接口是否也实现了其他接口,或者转换成其他接口:

最后更新于

这有帮助吗?