package main
import"fmt"// struct 定義結構體, 類似python中的類, 值類型type student struct{// 首字母大寫才外部可見
name string
age int
score int}// 構造函數, 這裏實際上和結構體沒有關係, 只是通過函數實例化一個結構體 funcnewStudent(name string, age, score int)*student {return&student{
name: name,
age: age,
score: score,// 逗號必不可少}}// 結構體的方法, 需要用 (s *stu) 聲明瞭接收的結構體, s爲約定俗稱的寫法func(s *stu)printScore(){
fmt.Println(s.score)}funcmain(){// 實例化
stu1 :=newStu("Tim",18,100)// 取值
fmt.Println(stu1.name, stu1.age, stu1.score)// 調用結構體方法
stu1.printScore()}
實例化的幾種寫法
package main
import"fmt"type stu struct{
name string
age int
score intfuncmain(){// 方法 1
p1 := stu{}// 沒有賦值, 結構體內所有的值都爲零值
fmt.Println(p1)// 方法 2
p2 :=new(stu)// 方法 3
p3 :=&stu{}
fmt.Println(p2, p3)// 得到的都是指針// 值類型: 初始化 = 實例化+賦值
stu2 := stu{
name:"a",
score:100,// 由於聲明瞭 key, 所以可以不按順序
age:18,}
fmt.Println(stu2)
stu3 := stu{"a",19,120,}
fmt.Println(stu3)}
指針接收者和值接收者
當需要修改結構體內部屬性的時候, 方法使用指針接收者
只需要取值的之後, 方法可以使用值接收者
package main
import"fmt"type stu struct{
name string
score int}// 值接收者, 適用於單純取值func(s stu)getScore(){
fmt.Println(s.score)}// 指針接收者, 適用於需要修改結構體的內部屬性時使用func(s *stu)setScore(newScore int){
s.score = newScore
}funcmain(){
stu1 := stu{name:"Tim", score:100}// 得到成績
stu1.getScore()// 更改成績
stu1.setScore(99)
fmt.Println(stu1.score)}
結構體的其他用法
嵌套結構體
package main
import"fmt"type address struct{
country string
city string}type person struct{
name string
age int
addr address
}funcmain(){
p1 := person{
name:"Tim",
age:22,
addr: address{
country:"中國",
city:"北京",},}
fmt.Println(p1.addr.city)// 必須一層一層找}
嵌套匿名結構體
package main
import"fmt"type address struct{
country string
city string}type person struct{
name string
age int
address
}funcmain(){
p1 := person{
name:"Tim",
age:22,
address: address{
country:"中國",
city:"北京",},}// 可以使用完整的, 也可以使用簡寫
fmt.Println(p1.address.city)
fmt.Println(p1.city)// city 在上一層必須沒有}
package main
// 並不推薦的一種寫法import"fmt"type cat struct{
name stringint// 未聲明屬性名, 只聲明瞭類型, 這種沒有屬性名的類型不可重複出現bool}funcmain(){
c1 := cat{name:"Tim",int:3,bool:true}
fmt.Println(c1)}
證明: 結構體中屬性的內存佈局
package main
import"fmt"// 結構體佔用連續內存空間funcmain(){type test struct{
a int16
b int16
c int16}var t = test{
a:1,
b:2,
c:3,}
fmt.Println(&(t.a))// 0xc000096000
fmt.Println(&(t.b))// 0xc000096001
fmt.Println(&(t.c))// 0xc000096002}