6.2. 方法
自定义类型除了可以通过结构体达到对成员数据的封装外,最大的作用是它们可以拥有方法。在凹语言中,方法是一类特殊的、依附于特定类型的函数,见下例:
// 版权 @2023 凹语言 作者。保留所有权利。
type Info struct {
name: string
age: i32
}
// 方法声明:
func Info.Print {
println("名字:", this.name, ",年龄:", this.age)
}
func main {
i := Info{name: "张三", age: 35}
i.Print() // 名字: 张三 ,年龄: 35
}
方法声明一般形式如下:
func 类型名.方法名(参数列表) => (返回值列表) {方法函数体}
方法声明与普通全局函数声明的区别是函数名的部分增加了 类型名.
。在方法体内部,this
是方法所属类型的引用,通过 this.
可读写其成员。
如果仅从目前已介绍的语法来看,方法和全局函数可以完成同样的功能,比如上述例子和下面的代码几乎等价:
// 版权 @2023 凹语言 作者。保留所有权利。
type Info struct {
name: string
age: i32
}
func Print(this: *Info) {
println("名字:", this.name, ",年龄:", this.age)
}
func main {
i := Info{name: "张三", age: 35}
Print(&i) // 名字: 张三 ,年龄: 35
}
如上例所示,如果把全局函数的第一个参数设为自定义类型的引用,那么它的作用和方法几乎是一致的——事实上在凹语言中,从运行时层面看,方法就是首参数为自定义类型引用的函数。既然如此,那么为何要特意引入这一概念呢?原因有两个:
- 方法有助于聚合对象的功能;
接口
这一概念直接依赖于方法——类型的方法集合决定了它所实现的接口,第7章将对此进行介绍。
需要特别注意的是,按照凹语言语法,使用
func T.xxx()...
声明的方法并不属于类型T
,而是属于类型*T
——既T
的引用;也就是说具名类型本身不能拥有方法,拥有方法的只能是具名类型的引用。