这是我参与「第五届青训营」伴学笔记创作活动的第6天。
这是Go语法笔记系列的第五篇,在这篇笔记中,我将总结和整理Go语言的结构体和接口等内容。
结构体(struct)
Go语言中并没有类(class)的概念,如果面向对象进行编程,通过struct会比较容易。在Go语言中,使用type关键字可以定义一个类型,struct属于一种type,因此struct的定义方法如下所示:
type user struct {
name string
passwd string
}
上面的语句定义了一个名为user的结构体,包括两个string类型的属性,分别名为name和passwd。
在创建结构体类型的变量时,语法与其他类型基本一样,但是可以通过{}的形式指定结构体变量属性的值:
a := user{name: "wang", password: "1024"}
b := user{"wang", "1024"}
c := user{name: "wang"}
c.password = "1024"
var d user
d.name = "wang"
d.password = "1024"
未被赋值的属性将被初始化为相应的空值(例如数值类型被赋为0,指针类型被赋为nil),在访问结构体变量的属性时,使用.操作符,例如上面的d.name
值得注意的是,因为Go语言中没有引用的概念,因此结构体变量作为函数参数传递时,传给函数的是结构体变量的拷贝而不是引用。
在Go语言中,可以声明属于各个类型的方法,这样的方法可以通过.操作符访问,类似于Java中的类的方法。要声明一个属于某一类型的方法,需要在函数名之前加上这个类型或者它的指针类型。例如:
type user struct {
name string
password string
}
func (u user) checkPassword(password string) bool {
return u.password == password
}
func (u *user) resetPassword(password string) {
u.password = password
}
上面的checkPassword和resetPassword函数都可以用.操作符通过user型变量访问,例如:
a := user{name: "wang", password: "1024"}
a.resetPassword("2048")
a.checkPassword("2048")
接口(interface)
Go语言中提供接口类型,开发者可以自己定义接口类型,以降低代码模块之间的耦合度,提高代码复用性。接口的定义方式和结构体很类似,如下:
type Phone interface {
call() int
}
上面的代码定义了一个名为Phone的接口,任何具有call() int方法的类型都被视为实现了这个接口。与结构体不同,接口内的属性是一个个函数声明。
type NokiaPhone struct {
}
func (nokiaPhone NokiaPhone) call() int {
fmt.Println("I am Nokia, I can call you!")
return 0
}
type IPhone struct {
}
func (iPhone IPhone) call() int {
fmt.Println("I am iPhone, I can call you!")
return 1
}
上面的NokiaPhone和IPhone两个结构体类型都有call() int方法,因此被视为实现了Phone接口,可以在任何需要Phone类型变量的地方使用。