栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Go语言

结构体【Go基础】

Go语言 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

结构体【Go基础】

文章目录
  • 自定义类型和类型别名
  • 结构体
    • 定义,初始化,构造函数,以及访问
    • 匿名结构体
    • 函数的传址和传值
    • 结构体指针
    • 结构体内存布局
    • 以结构体的方式体现内存对齐
    • 结构体匿名字段
    • 结构体嵌套
      • 嵌套匿名字段
      • 匿名嵌套结构体的字段名冲突

自定义类型和类型别名
package main

import "fmt"

//自定义类型和类型别名
//type后面跟的是类型

type myInt int //自定义类型

type yourInt = int

func main() {
	var n myInt = 100
	var m yourInt = 100
	fmt.Printf("%T, %vn", n, n) //main.myInt, 100
	fmt.Printf("%T, %v", m, m)   //int, 100
}
结构体

结构体是值类型

定义,初始化,构造函数,以及访问

可以安全地返回指向局部变量的指针,因为局部变量将在函数的作用域中继续存在(Go编译器使用栈逃逸机制将这种局部变量的空间分配在堆上)
并且不论通过结构体对象还是结构体指针来访问 结构体变量
都可以通过 . 进行,如果是结构体指针的话,指针将会被自动解引用
构造函数需要自己写,因为struct是值类型,所以需要返回指针类型,避免拷贝

package main

import "fmt"

type person struct {
	name string
	age  int
}

//可以安全地返回指向局部变量的指针,因为局部变量将在函数的作用域中继续存在
func newPerson(name string) *person {
	p := person{name: name, age: 42}
	return &p
}

func main() {
	p1 := person{name: "messi", age: 20}
	fmt.Printf("%T, %vn", p1, p1) //main.person, {messi 20}

	p2 := &person{name: "xavi", age: 25}
	fmt.Printf("%T, %vn", p2, p2) /
	s.age = 20
	s.name = "messi"
	fmt.Printf("%v, %T", s, s) //{messi 20}, struct { name string; age int }
}
函数的传址和传值
package main

import "fmt"

type person struct {
	name string
	age  int
}

func changePV(p person) {
	p.age++
}

func changePA(p *person) {
	//在Go中会自动对指针类型的变量进行解引用,所以不需要 (*p).age++
	p.age++
}

func main() {
	
	p1 := new(person)
	p1.age = 20
	p1.name = "messi"
	fmt.Printf("%#v, %Tn", p1, p1)

	changePV(*p1)
	fmt.Printf("after changePV%#v, %Tn", p1, p1) //

	changePA(p1)
	fmt.Printf("after changePA%#v, %Tn", p1, p1)
}
结构体指针
package main

import "fmt"

type person struct {
	name string
	age  int
}

func changePV(p person) {
	p.age++
}

func changePA(p *person) {
	//在Go中会自动对指针类型的变量进行解引用,所以不需要 (*p).age++
	p.age++
}

func main() {
	var pStruct_1 bool = false
	if pStruct_1 {
		p := new(person)
		//p.age = 20
		//p.name = "messi"
		fmt.Printf("%Tn", p)
		fmt.Printf("%vn", p)
		fmt.Printf("%pn", p)  //new出来的地址
		fmt.Printf("%pn", &p) //p变量本身的地址
	}

	//结构体初始化
	var pStruct_2 bool = false
	if pStruct_2 {
		p := person{
			name: "messi",
			age:  20,
		}
		fmt.Printf("%#vn", p)
	}

	//直接取结构体的地址进行初始化,相当于通过new初始化,并返回new出来的地址
	var pStruct_3 bool = true
	if pStruct_3 {
		p := &person{
			name: "messi",
			age:  20,
		}
		fmt.Printf("%%v:%#v, p本身的: %p, new申请的地址: %pn", p, &p, p)
		//%v:&main.person{name:"messi", age:20}, p本身的: 0x14000124018, new申请的地址: 0x1400011c018
	}
}
结构体内存布局
package main

import "fmt"

type person struct {
	a int64
	b int64
	c int64
}

func main() {
	n := person{
		a: 1,
		b: 2,
		c: 3,
	}
	fmt.Printf("&n  :%pn", &n)
	fmt.Printf("&n.a:%pn", &n.a)
	fmt.Printf("&n.b:%pn", &n.b)
	fmt.Printf("&n.c:%pn", &n.c)
	
}
以结构体的方式体现内存对齐

内存对齐

结构体匿名字段

使用匿名字段时,会将字段类型作为变量的名字,也就意味着同类型变量只能出现一次

package main

import "fmt"

type person struct {
	int
	string
}

func main() {
	p := person{20, "messi"}
	fmt.Printf("%Tn", p)
	fmt.Println(p.int)
}

但是可以通过自定义类型来出现多次,由此推测 只要编译时类型不一样就行,如下所示

package main

import "fmt"

type myInt int
type yourInt = int
type person struct {
	int
	string
	myInt
	yourInt
}

func main() {
	p := person{20, "messi", 20, 20}
	fmt.Printf("%T, %vn", p, p)
	fmt.Println(p.myInt)
}
结构体嵌套
package main

import "fmt"

type Address struct {
	sheng string
	shi   string
	qu    string
}

type person struct {
	name    string
	age     int
	address Address
}

func main() {
	p := person{name: "messi", age: 20, address: Address{
		sheng: "shanxi", shi: "xian", qu: "yanta"},
	}
	fmt.Println(p)
}
嵌套匿名字段

通过匿名字段,可实现对内部结构体变量的直接访问

package main

import "fmt"

type Address struct {
	sheng string
	shi   string
	qu    string
}

type person struct {
	name  string
	age   int
	Address
}

func main() {
	p := person{name: "messi", age: 20, Address: Address{
		sheng: "shanxi", shi: "xian", qu: "yanta"},
	}
	fmt.Println(p.sheng) //可直接访问Address中的sheng 
}

匿名嵌套结构体的字段名冲突

如果外层结构体和内层结构体存在字段名的冲突,则使用内层结构体的类型名作为字段名
对冲突字段进行访问
由此推断出,访问变量时,优先查找本层结构体

package main

import "fmt"

type Address struct {
	sheng string
	shi   string
	qu    string
}

type person struct {
	name  string
	age   int
	sheng string
	Address
}

func main() {
	p := person{name: "messi", age: 20, sheng: "beijing", Address: Address{
		sheng: "shanxi", shi: "xian", qu: "yanta"},
	}
	fmt.Println(p.sheng, p.Address.sheng)
}


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/945389.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号