结构体
结构体定义
type name struct{
value1 type1
value2 type2
......
}
组成结构体的数据称为字段,每一个字段有一个类型和一个名字,每一个字段的名字必须唯一,字段的类型任意。
创建结构体
type myStruct struct{
i1 int
f1 float32
str string
}
- 使用new
ms:=new(myStruct)
- 使用结构体字面量
var ms myStruct
- 间接使用new创建
ms:=&msStruct{10,1.1,"string"}
初始化结构体
ms:={1,1.1,“string”}
这种方法初始化必须按照字段在结构体定义是的顺序填写
ms:={i2:2.5,str:“hhh”}
这种方法指定某些字段的值,不必按照顺序,而且一些字段可以被忽略
使用结构体
import(
"fmt",
"string"
)
type Person struct{
firstName string
lastName string
}
func upPerson(p *Person){
p.firstName=strings.ToUpper(p.firstName)
p.lastName=strings.ToUpper(p.lastName)
}
func main(){
var per1 Person
per1.firstName="zhang"
per1.lastName="sang"
upPerson(&per1)
fmt.Printf("这个人的名字是%s %s\n",per1.firstName,per1.lastName)
per2:=new(Person)
per2.firstName="zhang"
per2.lastName="sang"
upPerson(&per2)
fmt.Printf("这个人的名字是%s %s\n",per2.firstName,per2.lastName)
per3:=&Person{"zhang","sang"}
upPerson(per3)
fmt.Printf("这个人的名字是%s %s\n",per3.firstName,per3.lastName)
}
注意
由于go的类型转换规则非常严格,当给一个结构体a取别名b时,就要进行类型转换
type number struct{
f int
}
type nb number
a:=number{1}
b:=nb{2}
a=b
//取了别名就不能直接赋值了a=b
//需要类型转换
//a=number(b)
fmt.Println(a)
结构体中的匿名字段
匿名字段就是没有名字只有类型的字段,在一个结构体中一种类型只能有一个匿名字段。
通过这个可以模拟类似继承的行为
type first struct{
f1 int
f2 int
}
type second struct{
s1 int
s2 int
first
}
func main(){
sec:=new(second)
sec.s1=1
sec.s2=2
sec.f1=3
sec.f2=4
fmt.Println(sec)
}
命名冲突
当一个结构体中两个字段有相同的名字的时候就会发生命名冲突(通过匿名字段实现继承的时候)
比如下面这几个例子
- 相同名字在同层次结构体中出现
type A struct{
a int
}
type B struct{
a int
b int
}
type C struct{
A
B
}
var c C
c.a
使用c.a就会报错,因为编译器分不清是c.A.a还是c.B.a
- 相同名字字段在不同结构体层次出现
type D struct{
B
b float32
}
var d D
d.b
这里使用d.b就没有问题,d.b和d.B.b是可以区分的