字段是結構體的一個組成部分,一般的數據類型、數組,引用類型等都是字段。
一:字段使用細節說明
①:字段聲明方式與普通聲明略有區別,如:字段Name string即可;
②:字段聲明后沒有賦值使用默認值,如引用類型默認值就是nil;
③:舉例1
string默認為空字符串,[ ]和map[ ]實質也是nil。
④:舉例2
由下代碼可知使用切片和map還需要make或同等作用的賦值才行。
package main import ( "fmt" ) //結構體 type Jgt struct { Name string Num int Arr [3]int Prt *int Slice []int M map[string]string } func main() { var jgt Jgt jgt.Name = "test1" fmt.Printf("jgt.Name=%v\n",jgt.Name) jgt.Num = 10 fmt.Printf("jgt.Num=%v\n",jgt.Num) jgt.Arr = [3]int{1,2,3} fmt.Printf("jgt.Arr=%v\n",jgt.Arr) jgt.Prt = &jgt.Num fmt.Printf("jgt.Prt=%v\n",*jgt.Prt) jgt.Slice = make([]int, 3) jgt.Slice[0] = 11 fmt.Printf("jgt.Slite=%v\n",jgt.Slice) jgt.M = map[string]string{ "name" : "louis", "age" : "18", "sex" : "male", } fmt.Printf("jgt.M=%v\n",jgt.M) } [ `go run struct1.go` | done ] jgt.Name=test1 jgt.Num=10 jgt.Arr=[1 2 3] jgt.Prt=10 jgt.Slite=[11 0 0] jgt.M=map[name:louis age:18 sex:male]
⑤:不同結構體變量的修改,互不影響
由上可知,不同的結構體變量在內存中使用不同的內存空間。
二:結構體變量訪問結構體字段的四種方法
①:var 結構體變量名稱 結構體
如:var jgt Jgt
②:var 結構體變量名稱 結構體=結構體{}
舉例
package main import ( "fmt" ) //結構體 type Jgt struct { Name string Age int } func main() { var jgt Jgt=Jgt{"張三",18} fmt.Println(jgt) }
結果 [ `go run struct1.go` | done ] {張三 18}
③:var 結構體變量名稱 *結構體=new(結構體)
舉例
package main import ( "fmt" ) //結構體 type Jgt struct { Name string Age int } func main() { var jgt *Jgt = new(Jgt) //因為jgt為指針所以要用指針方式賦值和輸出如:(*jgt).Name = "張三" //但由於Go在底層做了優化,會自動在前面加*,故也可以使用普通方法jgt.Age = 18 (*jgt).Name = "張三" jgt.Age = 18 //因為jgt為指針,如果使用不帶*號輸出前面會有&符號 //正常添加*號能解決&符號問題 fmt.Println(jgt) fmt.Println(*jgt) } 結果 [ `go run struct1.go` | done ] &{張三 18} {張三 18}
④:var 結構體變量名稱 *結構體 = &結構體{}
舉例
package main import ( "fmt" ) //結構體 type Jgt struct { Name string Age int } func main() { var jgt *Jgt = &Jgt{"張三", 18} (*jgt).Age = 19 fmt.Println(*jgt) } 結果 [ `go run struct1.go` | done ] {張三 19}
備注:其中③④方式返回的是結構體指針。
三:結構體字段使用細節
①:結構體變量里的字段在內存中是連續的。
②:結構體之間是可以相互轉換,但需要有完全相同的字段
package main import ( "fmt" ) //結構體 type A struct { Name string } type B struct { Name string } func main() { var a A var b B b = B(a) fmt.Println(a, b) }
③:結構體通過type重新定義,在Golang中被認為是一個新的類型,但仍然可以進行轉換(參考第②點)
④:每個字段都可以寫上tag,該tag可以通過反射機制獲取,從而實現序列化和反序列化
舉例
package main import ( "fmt" "encoding/json" ) //結構體 type Student struct { Name string `json:"name"` //`json:"name"` 就是tag,規定了序列化的格式 Age int `json:"age"` } func main() { var stu Student = Student{"張三", 18} json_str, err := json.Marshal(stu) if err != nil { fmt.Println("json數據失敗") } fmt.Println(string(json_str)) } 結果 [ `go run struct1.go` | done ] [123 34 110 97 109 101 34 58 34 229 188 160 228 184 137 34 44 34 97 103 101 34 58 49 56 125] {"name":"張三","age":18}