结构体
结构体定义
type name struct{value1 type1value2 type2......
}
组成结构体的数据称为字段,每一个字段有一个类型和一个名字,每一个字段的名字必须唯一,字段的类型任意。
创建结构体
type myStruct struct{i1 intf1 float32str 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 stringlastName string
}
func upPerson(p *Person){p.firstName=strings.ToUpper(p.firstName)p.lastName=strings.ToUpper(p.lastName)
}
func main(){var per1 Personper1.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 numbera:=number{1}b:=nb{2}a=b//取了别名就不能直接赋值了a=b//需要类型转换//a=number(b)fmt.Println(a)
结构体中的匿名字段
匿名字段就是没有名字只有类型的字段,在一个结构体中一种类型只能有一个匿名字段。
通过这个可以模拟类似继承的行为
type first struct{f1 intf2 int
}
type second struct{s1 ints2 intfirst
}
func main(){sec:=new(second)sec.s1=1sec.s2=2sec.f1=3sec.f2=4fmt.Println(sec)
}
命名冲突
当一个结构体中两个字段有相同的名字的时候就会发生命名冲突(通过匿名字段实现继承的时候)
比如下面这几个例子
- 相同名字在同层次结构体中出现
type A struct{a int
}
type B struct{a intb int
}
type C struct{AB
}
var c C
c.a
使用c.a就会报错,因为编译器分不清是c.A.a还是c.B.a
- 相同名字字段在不同结构体层次出现
type D struct{Bb float32
}
var d D
d.b
这里使用d.b就没有问题,d.b和d.B.b是可以区分的