天天看點

Golang struct結構

結構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))
}