11-结构体
结构体
什么是结构体
结构体是用户定义的类型,表示若干个字段(Field)的集合。有时应该把数据整合在一起,而不是让这些数据没有联系。这种情况下可以使用结构体。一系列属性的集合
结构体的定义
type 结构体名字 struct{}
//定义一个人的结构体
type Person struct{
name string
sex int
age int //如果是存在相同类型的可以写成: sex,age int
}
匿名结构体(没有type和名字)
package main import "fmt" func main() { //创建匿名结构体并赋值 a:= struct { name string age int }{"aaa",20} //赋值 fmt.Println(a) } #结果 {aaa 20}
创建结构体并赋值
package main import "fmt" //定义person结构体 type Person struct { name string age,sex int } func main() {
#第一种赋值方式 ,根据key,value形式 person1:=Person{ name:"bob", age:10, sex:1, }
#第二种赋值方式,位置传参 person2:=Person{"jj",20,0}
fmt.Println(person1) fmt.Println(person2) } #结果 {bob 10 1} {jj 20 0}
结构体的零值(打印出来是0,说明结构体是值类型)
package main import "fmt" //定义person结构体 type Person struct { name string age,sex int } func main() { var person Person //也可以这样写person:=Person{} fmt.Println(person) } #结果 { 0 0}
访问结构体的字段
点号操作符 . 用于访问结构体的字段
package main import ( "fmt" ) type Employee struct { firstName, lastName string age, salary int } func main() { emp6 := Employee{"Sam", "Anderson", 55, 6000} //结构体赋值 fmt.Println("First Name:", emp6.firstName) fmt.Println("Last Name:", emp6.lastName) fmt.Println("Age:", emp6.age) fmt.Printf("Salary: $%d", emp6.salary) }
结构体的指针
还可以创建指向结构体的指针
package main import "fmt" //定义person结构体 type Person struct { name string age,sex int } func main() { #不同种定义方式 person2:=&Person{"jj",20,0} var person3 =&Person{"xx",30,1} fmt.Println((*person2).name) //jj fmt.Println((*person3).name) //xx fmt.Println(person2.name) //jj fmt.Println(person3.name) //xx }
Go语言允许我们在访问name字段的时候,可以使用person2.name代替(*person2).name,写起来更方便简洁。
匿名字段
当我们创建结构体时,字段可以只有类型,而没有字段名。这样的字段称为匿名字段。
以下代码创建一个 Person
结构体,它含有两个匿名字段 string
和 int
。
type Person struct {
string
int
}
package main import ( "fmt" ) type Person struct { string int } func main() { p := Person{"Naveen", 50} fmt.Println(p) } #结果 {Naveen 50}
虽然匿名字段没有名称,但其实匿名字段的名称就默认为它的类型。比如在上面的 Person
结构体里,虽说字段是匿名的,但 Go 默认这些字段名是它们各自的类型。所以 Person
结构体有两个名为 string
和 int
的字段。
package main import ( "fmt" ) type Person struct { string int } #匿名函数也可以根据它们的类型来赋值 func main() { var p1 Person p1.string = "naveen" p1.int = 50 fmt.Println(p1) }
嵌套结构体
结构体的字段有可能也是一个结构体。这样的结构体称为嵌套结构体。
package main import ( "fmt" ) type Address struct { city, state string } type Person struct { name string age int address Address #嵌套结构体:字段名+结构体 } func main() { var p Person p.name = "Naveen" p.age = 50 p.address = Address { city: "Chicago", state: "Illinois", } fmt.Println("Name:", p.name) fmt.Println("Age:",p.age) fmt.Println("City:",p.address.city) fmt.Println("State:",p.address.state) }
//嵌套结构体另一种赋值方式 p:=Person{name:"lqz",hobby:Hobby{10,"篮球"}} p:=Person{name:"lqz",hobby:Hobby{id:10,name:"篮球"}} p.hobby.id=101
提升字段(结构体嵌套+匿名字段)(******)
//结构体嵌套+匿名字段 type Person struct { name string sex ,age int Hobby } type Hobby struct { id int hobbyname string } func main() { //结构体嵌套加匿名字段 p:=Person{name:"lqz",Hobby:Hobby{10,"篮球"}} //取p中的hobbyname,匿名函数可以不用通过结构体直接取到属性值,属性名没有和嵌套结构体中有重名的才可以这样 fmt.Println(p.Hobby.hobbyname) fmt.Println(p.hobbyname) } #结果 篮球 篮球
下面这个是有重名的属性,变量就不会提升了(类似于面向对象中的继承)
//结构体嵌套+匿名字段 type Person struct { name string sex ,age int Hobby } type Hobby struct { id int name string } func main() { //结构体嵌套加匿名字段 p:=Person{name:"lqz",Hobby:Hobby{10,"篮球"}} //取p中的name,属性name和嵌套结构体中有重名的属性,如果直接用p.name这种方法就会找结构体中的name属性,不会提升 fmt.Println(p.Hobby.name) fmt.Println(p.name) } #结果 篮球 lqz
结构体相等性
结构体是值类型。如果它的每一个字段都是可比较的,则该结构体也是可比较的。如果两个结构体变量的对应字段相等,则这两个变量也是相等的。
package main import ( "fmt" ) type name struct { firstName string lastName string } func main() { name1 := name{"Steve", "Jobs"} name2 := name{"Steve", "Jobs"} if name1 == name2 { fmt.Println("name1 and name2 are equal") } else { fmt.Println("name1 and name2 are not equal") } name3 := name{firstName:"Steve", lastName:"Jobs"} name4 := name{} name4.firstName = "Steve" if name3 == name4 { fmt.Println("name3 and name4 are equal") } else { fmt.Println("name3 and name4 are not equal") } }