什么是结构体
结构体是用户定义的类型,表示若干个字段的集合,有时应该把数据整合一起,而不是让这些数据没有联系,这种情况下可以使用结构体
语法
// 结构体 //type关键字 结构体名字 struct{ // 字段1 字段类型 // 字段2 字段类型 //}
结构体定义
type Person struct { // 如果小写,在其他包使用不到Person结构体 Name string // 字段大写,表示导出,如果小写,表示隐藏,在其他包中取不到 age uint8 Sex string }
使用结构体
结构体是值类型,有默认零值,如果当函数参数传递,在函数中修改,不会影响原来的
package main import "fmt" type Person struct { // 如果小写,在其他包使用不到Person结构体 Name string // 字段大写,表示导出,如果小写,表示隐藏,在其他包中取不到 age uint8 Sex string } func main() { var p Person // 没有初始化,有零值,零值是每个字段的零值 fmt.Println(p.age) //0 有默认零值,字段的零值 fmt.Println(p) //{ 0 } }
定义并初始化
按位置初始化
按照顺序,有几个字段,必须传几个字段
package main import "fmt" type Person struct { // 如果小写,在其他包使用不到Person结构体 Name string // 字段大写,表示导出,如果小写,表示隐藏,在其他包中取不到 age uint8 Sex string } func main() { var p Person=Person{"zys",18,"男"} fmt.Println(p) //{zys 18 男} }
按关键字初始化
不用按顺序,字段不用都传
package main import "fmt" type Person struct { // 如果小写,在其他包使用不到Person结构体 Name string // 字段大写,表示导出,如果小写,表示隐藏,在其他包中取不到 age uint8 Sex string } func main() { var p Person=Person{Sex:"男",age:19} fmt.Println(p) //{ 19 男} }
字段的取值赋值
通过.
package main import "fmt" type Person struct { // 如果小写,在其他包使用不到Person结构体 Name string // 字段大写,表示导出,如果小写,表示隐藏,在其他包中取不到 age uint8 Sex string } func main() { var p Person=Person{Sex:"男",age:19} fmt.Println(p) //{ 19 男} fmt.Println(p.Name) p.Name="xx" fmt.Println(p.Name) //xx }
结构体零值
不初始化有默认零值,零值是各个字段的零值
package main import "fmt" type Person struct { // 如果小写,在其他包使用不到Person结构体 Name string // 字段大写,表示导出,如果小写,表示隐藏,在其他包中取不到 age uint8 Sex string } func main() { var p Person fmt.Println(p) //{ 0 } }
匿名结构体
结构体没有名字和type关键字,一般定义在函数内部,只使用一次
好处是:多个变量可以包装到一个变量中
func main() { a:= struct { age int name string }{19,"彭于晏"} fmt.Println(a.name) fmt.Println(a.age) fmt.Println(a) }
结构体指针
还可以创建只想结构体的指针
package main import ( "fmt" ) type Employee struct { firstName, lastName string age, salary int } func main() { emp8 := &Employee{"Sam", "Anderson", 55, 6000} fmt.Println("First Name:", (*emp8).firstName) fmt.Println("Age:", (*emp8).age) }
在上面程序中,emp8 是一个指向结构体 Employee
的指针。(*emp8).firstName
表示访问结构体 emp8
的 firstName
字段。该程序会输出
First Name: Sam Age: 55
Go 语言允许我们在访问 firstName
字段时,可以使用 emp8.firstName
来代替显式的解引用 (*emp8).firstName
。
package main import ( "fmt" ) type Employee struct { firstName, lastName string age, salary int } func main() { emp8 := &Employee{"Sam", "Anderson", 55, 6000} fmt.Println("First Name:", emp8.firstName) fmt.Println("Age:", emp8.age) }
在上面的程序中,我们使用 emp8.firstName
来访问 firstName
字段,该程序会输出:
First Name: Sam Age: 55
结构体当函数参数传递
package main import "fmt" type Person struct { // 如果小写,在其他包使用不到Person结构体 Name string // 字段大写,表示导出,如果小写,表示隐藏,在其他包中取不到 age uint8 Sex string } func main() { var p =Person{"zys",18,"男"} test5(p) fmt.Println("----",p) // p 不受影响 ---- {zys 18 男} } func test5(p Person) { fmt.Println(p) //{zys 18 男} p.Name="lyf" fmt.Println(p) //{lyf 18 男} }
结构体指针当函数参数传递
package main import "fmt" type Person struct { // 如果小写,在其他包使用不到Person结构体 Name string // 字段大写,表示导出,如果小写,表示隐藏,在其他包中取不到 age uint8 Sex string } func main() { var p = &Person{"zys", 18, "男"} test6(p) //指针传入,地址copy传入,改了就影响原来 fmt.Println("----", p) // p 受影响 ---- &{lyf 18 男} } func test6(p *Person) { fmt.Println(p) //&{zys 18 男} p.Name = "lyf" //(*p).Name="lyf" fmt.Println(p) //&{lyf 18 男} }
匿名字段
字段没有名字,跟结构体是否匿名没有必然联系
作用:可以做字段提升,实现面向对象的继承
package main import "fmt" type Animal struct { string // 字段没有名字,但是不能出现两个同种类型的字段 ,字段名就是类型名 int } func main() { //var a =Animal{"小鸭子",1} var a = Animal{string: "小鸭子", int: 1} fmt.Println(a) //{小鸭子 1} }
结构体嵌套
结构体中套结构体
package main import "fmt" func main() { type Animal struct { Name string age int } type Dog struct { //Name string //age int // 简写成--->结构体嵌套 //animal Animal Animal //匿名字段,Animal字段匿名了,字段名就是类型名,而且不用写name和age了 //Dog比Animal多的字段 Speak bool } //var dog =Dog{Animal{"二哈",3},true} var dog = Dog{Animal: Animal{"二哈", 3}, Speak: true} //面向对象继承,1 少写代码 2 子类对象.属性 如果子类没有,直接使用父类的 fmt.Println(dog.Name) //二哈 dog的name本来是Animal的,使用了匿名字段,字段提升了 //如果Animal不是匿名字段,不能提升 fmt.Println(dog.Animal.Name) //二哈 指名道姓用 dog.Animal 相当于 super() //Dog中有Name,Animal 用了匿名字段,Name冲突了,会优先使用Dog自己的 }
导出结构体和字段
package main import ( "day01/entity" "fmt" ) type Person struct { // 如果小写,在其他包使用不到Person结构体 Name string // 字段大写,表示导出,如果小写,表示隐藏,在其他包中取不到 age uint8 Sex string } func main() { //var p =entity.Person{"lyf",37} // age 小写,外包包不能用 var p =entity.Person{Name:"lyf"} fmt.Println(p) //{lyf 0} }
entity包
package entity type Person struct { // 大写开头,外包才可以用 Name string age int }
结构体是值类型
package main import ( "fmt" ) type Person struct { // 如果小写,在其他包使用不到Person结构体 Name string // 字段大写,表示导出,如果小写,表示隐藏,在其他包中取不到 age uint8 Sex string } func main() { //如果它的每一个字段都是可比较的,则该结构体也是可比较的。 //如果两个结构体变量的对应字段相等,则这两个变量也是相等的 var p1=Person{"zys",19,"男"} var p2=Person{Name: "zys",age: 19,Sex: "男"} p2.age=20 if p1==p2{ fmt.Println("p1 和p2 相等") }else{ fmt.Println(1) //1 } //如果结构体包含不可比较的字段(有引用类型),则结构体变量也不可比较 //type Cat struct { //Name string //age int //wife []string // 可以有很多异性猫 //} //var c1 =Cat{"小野豹",3,[]string{"女朋友1号","女朋友2号"}} //var c2 =Cat{"小野豹",3,[]string{"女朋友1号","女朋友2号"}} //if c1==c2{ // //} }
标签:Println,main,Name,fmt,Person,go,结构,string From: https://www.cnblogs.com/zhaoyuanshi/p/16707151.html