一、 结构体(struct)
1、结构体定义
type identifier struct {
field1 type1
field2 type2
...
}
声明:new(Type) 和 &Type{}是等价的
2、初始化结构体
type Interval struct {
start int
end int
}
初始化方式:
intr := Interval{0, 3} (A)
intr := Interval{end:5, start:1} (B)
intr := Interval{end:5} (C)
3、 使用工厂方法创建结构体
type matrix struct {
...
}
func NewMatrix(params) *matrix {
m := new(matrix) // 初始化 m
return m
}
在其他包里使用工厂方法:
package main
import "matrix"
...
wrong := new(matrix.matrix) // 编译失败(matrix包中的matrix结构体小写 是私有的)
right := matrix.NewMatrix(...) // 实例化 matrix 的唯一方式
注意:试图 make() 一个结构体变量,会引发一个编译错误
4、 带标签的结构体
结构体中的字段除了有名字和类型外,还可以有一个可选的标签(tag):它是一个附属于字段的字符串,可以是文档或其他的重要标记。
标签的内容不可以在一般的编程中使用,只有包 reflect 能获取它。
例子:
package main
import (
"fmt"
"reflect"
)
type TagType struct { // tags
field1 bool "An important answer"
field2 string "The name of the thing"
field3 int "How much there are"
}
func main() {
tt := TagType{true, "Barak Obama", 1}
for i := 0; i < 3; i++ {
refTag(tt, i)
}
}
func refTag(tt TagType, ix int) {
ttType := reflect.TypeOf(tt)
ixField := ttType.Field(ix)
fmt.Printf("%v\n", ixField.Tag)
}
输出:
An important answer
The name of the thing
How much there are
5| 匿名字段和内嵌结构体
结构体可以包含一个或多个 匿名(或内嵌)字段,即这些字段没有显式的名字,只有字段的类型是必须的,此时类型就是字段的名字。
匿名字段本身可以是一个结构体类型,即 结构体可以包含内嵌结构体。
在一个结构体中对于每一种数据类型只能有一个匿名字段。
二、方法(method)
Go 方法是作用在接收者(receiver)上的一个函数,接收者是某种类型的变量。因此方法是一种特殊类型的函数。
接收者类型可以是(几乎)任何类型,不仅仅是结构体类型:任何类型都可以有方法,甚至可以是函数类型,可以是 int、bool、string 或数组的别名类型。
但是接收者不能是一个接口类型(参考 第 11 章),因为接口是一个抽象定义,但是方法却是具体实现;
如果这样做会引发一个编译错误:invalid receiver type…。
方法的格式:
func (recv receiver_type) methodName(parameter_list) (return_value_list) { … }
func (_ receiver_type) methodName(parameter_list) (return_value_list) { … }
函数和方法的区别
函数将变量作为参数:Function1(recv)
方法在变量上被调用:recv.Method1()