go 结构体
结构体是复合类型(composite types),当需要定义一个类型,它由一系列属性组成,每个属性都有自己的类型和值的时候,就应该使用结构体,它把数据聚集在一起。然后可以访问这些数据,就好像它是一个独立实体的一部分。
定义
结构体定义的一般方式如下:
type Identifier struct {
field1 type1
field2 type2
...
}
赋值
结构体是值类型,因此可以通过 new 来创建。
我们可以使用 .
给字段赋值:
structname.fieldname = value
同样的,也可以使用 .
获取结构体字段的值:
structname.fieldname
在 Go 语言中这叫 selector。无论变量是一个 结构体类型
还是一个 结构体类型指针
,都使用同样的 selector-notation 来引用结构体的字段:
type myStruct struct { i int }
var v myStruct // v 是结构体类型变量
var p *myStruct // p 是指向一个结构体类型变量的指针
v.i
p.i
下面来看一个例子
// rectangle.go
package rect
type Rectangle struct {
length int
width int
}
func (r *Rectangle) Set(x,y int) {
r.length = x
r.width = y
}
func (r *Rectangle) Area() (res int) {
res = r.length * r.width
return
}
func (r *Rectangle) Perimeter() (res int) {
res = (r.length + r.width) * 2
return
}
// main.go
package main
import (
"rect"
"fmt"
)
func main() {
rectangle := new(rect.Rectangle)
rectangle.Set(1, 2)
fmt.Println("rectangle is",rectangle)
fmt.Println(rectangle.Area())
fmt.Println(rectangle.Perimeter())
}
运行结果
rectangle is &{1 2}
2
6
注意:如果 XX 是一个结构体类型,那么表达式
new(XX)
和&XX{}
是等价的。
例如:
type MyStruct struct {
x int
y int
}
my := new(MyStruct)
my.x = 1
my.y = 2
等价于
my2 := &Mystrcut{1, 2}
工厂方法
你现在突然想,不能让别人看到我的结构体,我应该把它设为私有的,但是还想让别人使用我的结构体,该怎么办?
为了方便,通常会为类型定义一个工厂,按惯例,工厂的名字以 new 或 New 开头,它返回一个指向结构体实例的指针。形式如下:
// mystruct.go
package my
type mystruct struct {
...
}
func NewMystruct() *mystruct {
m : = new(mystruct) // 初始化 m
return m
}
在其他包里使用工厂方法:
// main.go
package main
import "my"
...
wrong : = new(my.mystruct) // 编译失败,mystruct 是私有的
right : = my.NewMystruct() // 实例化 mystruct 的唯一方式