Golang 结构体

Golang 结构体

定义

注意!!!Go中结构体是值类型, 不同于Java中的类是引用类型

type typeName struct{//如果结构体名为小写就表示只能被当前包使用, 反之可以被所有包使用
	filed type //字段
	filed type //指针, slice 和map零值都为nil
}

创建结构体

方式一: var identifier type

type cat struct {
	Name string
	age int
}
func main() {
	var mimi cat
	mimi.Name = "小花"
	mimi.age = 3
	fmt.Println(mimi)
}

方式二: identifier := type{}

type cat struct {
	Name string
	age int
}
func main() {
	//类似于构造器
	mimi := cat{"mimi", 10}
	fmt.Println(mimi)
}

方式三: var identifier *type = new(type)

创建一个指针

func main() {
    //创建一个指针类型 new(cat){}错误
    cat1 := new(cat)// 等价于  cat1 := new(cat)
	(*cat1).Name = "猪皮"
	cat1.Name = "中分" //等价于上面的方式
	(*cat1).age =3
	cat1.age = 10
	fmt.Println(cat1)
}

方式四: var identifier *type = &type{}

func main() {
	//指针存储地址
	var cat1 *cat = &cat{"mimi",10}//等价于 cat1 := &cat{"mimi", 10}
	(*cat1).Name = "猪皮"
	cat1.Name = "中分" //等价于上面的方式
	fmt.Println(cat1)
}

注意点

  1. Go中结构体是值类型, 实例对象相互不会影响

    func main() {
    	cat1 := cat{"小花",4}
    	//拷贝cat1的值赋值给cat2
    	cat2 := cat1
    	cat2.Name = "mimi"
    	fmt.Println(cat1) //{小花 4}
    	fmt.Println(cat2) //{mimi 4}
    }
    
  2. 结构体的所有字段在内存中是连续的, 包括指针变量

    type Point struct {
    	x, y int
    }
    type Rect struct {
    	left, right Point
    }
    func main() {
    	//结构体的所有字段在内存中是连续的
    	rect := Rect{Point{3, 10}, Point{1, 2}}
    	fmt.Printf(`%v,%v,%v,%v`,
    		&rect.left.x,
    		&rect.left.y,
    		&rect.right.x,
    		&rect.right.y)
    }
    
    type Point struct {
    	x, y int
    }
    type Rect struct {
    	left, right *Point
    }
    
    func main() {
    	rect := Rect{&Point{3, 10},
    		&Point{1, 2}}
    	fmt.Printf(`%p,%p,%p,%p`,
    		&rect.right.x,
    		&rect.right.y,
    		&rect.left.x,
    		&rect.left.y)
    }
    
  3. 结构体之间支持强转, 但是字段必须完全相同(字段名, 数量, 类型)

    type A struct {
    	num int
    }
    type B struct {
    	num int
    }
    func main() {
    	var a A
    	var b B
    	//如果字段名,字段类型,字段个数相同就可以强转
    	a = A(b)
    	fmt.Println(a,b)
    }
    
  4. 结构体支持别名, 但是相互间可以强转

    type Person struct {
    	name string
    	age int
    }
    //结构体支持别名
    type p Person
    func main() {
    	var stu p = p{"张三",10}
    	fmt.Printf("%v", stu)
        ----------------------
        var stu1 Person
    	var stu2 p
    	//stu1 = stu2错误
        stu1 = Person(stu2)
    }
    
  5. 结构体转Json

    type Monster struct {
    	Name  string
    	Age   int
    	skill string
    }
    func main() {
    	monster := Monster{"beast", 10, "Giao~"}
    	//只会转换公开的字段, 因为使用其他包, 其他包不能访问私有变量
    	json, _ := json.Marshal(monster)
    	jsonStr := string(json)
    	fmt.Println(jsonStr)
    }
    

    使用tag为字段名取别名

    type Monster struct {
    	//tag相当于给字段名取别名, 类型于@JsonProperty
    	Name  string `json:"name"`
    	Age   int    `json:"age"`
    	skill string `json:"skill"` //私有的字段同样不能访问
    }
    func main() {
    	monster := Monster{"beast", 10, "Giao~"}
    	//只会转换公开的字段, 因为使用其他包, 其他包不能访问私有变量
    	json, _ := json.Marshal(monster)
    	jsonStr := string(json)
    	fmt.Println(jsonStr)
    }
    
原文地址:https://www.cnblogs.com/kikochz/p/13488232.html