結構struct
- Go中的struct與C中的struct非常相似,并且Go沒有class,代替了class的位置,但并沒有代替class的功能
- 使用type struct{} 定義結構,名稱遵循可見性規則
- 支援指向自身的指針類型成員
- 支援匿名結構,可用作成員或定義成員變量
- 匿名結構也可以用于map的值
- 可以使用字面值對結構進行初始化
- 允許直接通過指針來讀寫結構成員
- 相同類型的成員可進行直接拷貝指派
- 支援==與!=比較運算符,但不支援>或<
- 支援匿名字段,本質上是定義了以某個類型名為名稱的字段
- 嵌入結構作為匿名字段看起來像繼承,但不是繼承
- 可以使用匿名字段指針
- tag是結構體的元資訊,可以在運作的時候通過反射機器讀取出來;字段類型的後面,以反引号擴起來的key-value結構的字元串,多個tag以逗号隔開。
結構的定義
package main
import (
"fmt"
)
type Person struct { //結構也是一中類型
Name string //定義struct的屬性
Age int
}
func main() {
a := Person{}
a.Name = "joe" //對struct的屬性進行操作,類型與class的使用方法
a.Age = 19
fmt.Println(a)
}
字面值初始化
package main
import (
"fmt"
)
type Person struct {
Name string
Age int
}
func main() {
a := Person{
Name: "jack",
Age: 19, //對結構的屬性進行字面值的初始化
}
fmt.Println(a)
}
結構的傳遞
package main
import (
"fmt"
)
type Person struct {
Name string
Age int
}
func main() {
a := Person{
Name: "jack",
Age: 19, //對結構的屬性進行字面值的初始化
}
fmt.Println(a)
A(a)
fmt.Println(a) //結構也是一種值類型,對它進行傳遞的時候,也是進行了值得拷貝
}
func A(per Person) {
per.Age = 13
fmt.Println("A", per)
}
PS G:\mygo\src\mytest> go run .\temp.go
{jack 19}
A {jack 13}
{jack 19}
package main
import (
"fmt"
)
type Person struct {
Name string
Age int
}
func main() {
a := Person{
Name: "jack",
Age: 19, //對結構的屬性進行字面值的初始化
}
fmt.Println(a)
A(&a)
fmt.Println(a) //結構也是一種值類型,對它進行傳遞的時候,也是進行了值得拷貝
}
func A(per *Person) { //通過一個指針進行傳遞,此時就不是值得拷貝了
per.Age = 13
fmt.Println("A", per)
}
PS G:\mygo\src\mytest> go run .\temp.go
{jack 19}
A &{jack 13}
{jack 13}
package main
import (
"fmt"
)
type Person struct {
Name string
Age int
}
func main() {
a := &Person{
Name: "jack",
Age: 19, //此時初始化的時候就将這個struct的指針取出來
}
//在進行struct的初始化的時候,就加上&取位址符号
fmt.Println(a)
A(a)
B(a)
fmt.Println(a) //結構也是一種值類型,對它進行傳遞的時候,也是進行了值得拷貝
}
func A(per *Person) { //通過一個指針進行傳遞,此時就不是值得拷貝了
per.Age = 13
fmt.Println("A", per)
}
func B(per *Person) { //通過一個指針進行傳遞,此時就不是值得拷貝了
per.Age = 15
fmt.Println("B", per)
}
PS G:\mygo\src\mytest> go run .\temp.go
&{jack 19}
A &{jack 13}
B &{jack 15}
&{jack 15}
匿名結構
package main
import (
"fmt"
)
func main() {
a := &struct { //匿名結構,需要先對結構本身進行一個定義
Name string
Age int
}{
Name: "jack",
Age: 20,
}
fmt.Println(a)
}
匿名結構的嵌套
package main
import (
"fmt"
)
type Person struct {
Name string
Age int
Contact struct {
Phone, City string //匿名結構嵌套在Person中
}
}
func main() {
a := Person{Name: "Jack", Age: 20}
a.Contact.Phone = "123321" //通過這種方法對嵌套在Person中的匿名結構進行字面值的初始化
a.Contact.City = "BeiJing"
fmt.Println(a)
}
PS G:\mygo\src\mytest> go run .\temp2.go
{Jack 20 {123321 BeiJing}}
匿名字段
package main
import (
"fmt"
)
type Person struct {
string //匿名字段 在進行字面值初始化的時候 必須嚴格按照字段聲明的順序
int
}
func main() {
a := Person{"Jack", 20} //此時将string 和 int類型對調的時候就會報錯
fmt.Println(a)
}
結構相同類型的比較
package main
import (
"fmt"
)
type Person struct {
Name string
Age int
}
func main() {
a := Person{Name: "Jack", Age: 20}
b := Person{Name: "Jack", Age: 20}
fmt.Println(a == b)
}
PS G:\mygo\src\mytest> go run .\temp3.go
true
嵌入結構
package main
import (
"fmt"
)
type human struct {
Sex int
}
type teacher struct {
human
Name string
Age int
}
type student struct {
human //這裡的human也是一種類型,此時它相當于一種匿名字段,嵌入結構作為匿名字段的話
//它本質上是将結構名稱作為我們的字段名稱
Name string
Age int
}
func main() {
a := teacher{Name: "Jack", Age: 20, human: human{Sex: 0}} //是以我們需要在這裡進行這種初始化
b := student{Name: "Tom", Age: 19, human: human{Sex: 1}}
a.Name = "Fack"
a.Age = 13
a.human.Sex = 100 //保留這種調用的方法,是因為會涉及到名稱的沖突
//a.Sex = 101 這種寫法也是可以的
fmt.Println(a, b)
}
PS G:\mygo\src\mytest> go run .\temp3.go
{{100} Fack 13} {{1} Tom 19}
tag的詳解
package main
import (
"encoding/json"
"fmt"
)
type User struct {
Username string `json:"username"`
Sex string `json:"sex"`
Age int
AvatarUrl string
}
func main() {
user := &User{
Username: "user01",
Sex: "男",
Age: 18,
AvatarUrl: "http://xxx.xxx.com/xxx.png",
}
data, _ := json.Marshal(user)
fmt.Printf("json str:%s\n", string(data))
}