GoLang学习笔记(三十一)结构体及匿名结构体、匿名字段

结构体

数组可以存储同一类的数据,但在结构体中,我们可以为不同项定义不同的数据类型。
结构体是由一系列具有相同类型或不同类型的数据构成的数据集合。
结构体的定义格式:
type 类型名 struct {
    成员属性1 类型1
    成员属性2 类型2
    成员属性3 成员属性4 类型3
    ...
}
类型名,表示结构体的名称,在同一个包内不能重复。
结构体中的属性,也叫字段必须唯一。
同类型的成员属性可以写在一行。

type teacher struct {
	name string
	age  int8
	sex  byte
}

结构体的定义只是一种内存布局的描述,只有当结构体实例化了,才会真正分配内存。
必须在实例化后才能使用结构体。
实例化就是根据结构体定义的格式创建一份与格式一致的内存区域。
结构体实例之间的内存是完全独立的。

先声明一个print函数,方便输入后面的代码。

func printTeacher(t teacher) {
	fmt.Printf("姓名:%v,年龄:%d,性别%v  \n", t.name, t.age, t.sex)
}

声明一个结构体,并打印信息。

var t0 teacher
printTeacher(t0)

var格式声明方式实例化结构体。

var t1 teacher
t1.name = "t1"
t1.age = 30
t1.sex = 0
printTeacher(t1)

短变量声明格式实例化结构体。

t2 := teacher{}
t2.name = "t2"
t2.age = 35
t2.sex = 1
printTeacher(t2)

用简短声明格式实例化结构体,并初始化。

t3 := teacher{
	"t3",
	40,
	1,
}
printTeacher(t3)
t4 := teacher{"t4", 50, 0}
printTeacher(t4)

创建指针类型的结构体:
使用内置函数new()对结构体进行实例化,结构体实例化后形成的指针类型的结构体。
new函数会分配内存,第一个采纳数是类型,而不是值,返回的值是指向该类型新分配的零值指针。
盖函数用于创建某个类型的指针。

t5 := new(teacher)
//标准写法
(*t5).name = "t5"
(*t5).age = 55
//简化写法(语法糖)
t5.sex = 1
printTeacher(*t5)

结构体是一个值类型:

func testNewClass2() {
	t1 := teacher{"t1", 21, 1}
	fmt.Printf("t1 : %T , %v , %p \n", t1, t1, &t1)
	fmt.Println("--------------")
	t2 := t1
	t2.name = "t2"
	t2.age = 22
	fmt.Printf("t1 : %T , %v , %p \n", t2, t2, &t2)
	fmt.Printf("t1 : %T , %v , %p \n", t1, t1, &t1)
}

结构体是一个值类型,属于深拷贝,可以引用结构体的地址来进行浅拷贝。

func testClass3() {
	t1 := teacher{"t1", 10, 1}
	fmt.Printf("t1的姓名:%v,t1的年龄:%v,t1的性别:%v \n", t1.name, t1.age, t1.sex)
	//深拷贝
	t2 := t1
	t2.name = "t2"
	t2.age = 20
	t2.sex = 0
	fmt.Printf("t2的姓名:%v,t2的年龄:%v,t2的性别:%v \n", t2.name, t2.age, t2.sex)
	fmt.Printf("修改t2后t1的姓名:%v,t1的年龄:%v,t1的性别:%v \n", t1.name, t1.age, t1.sex)
	fmt.Println("---------------------------------")

	//浅拷贝
	t3 := &t1
	t3.name = "t3"
	t3.age = 30
	t3.sex = 0
	fmt.Printf("t2的姓名:%v,t2的年龄:%v,t2的性别:%v \n", t3.name, t3.age, t3.sex)
	fmt.Printf("修改t2后t1的姓名:%v,t1的年龄:%v,t1的性别:%v \n", t1.name, t1.age, t1.sex)
	fmt.Println("---------------------------------")
}

将结构体作为函数参数

func testClass4(t teacher) {
	t.name = "修改以后"
	t.age = 99
	t.sex = 0
	printTeacher(t)
}

将结构体指针作为函数参数

func testClass5(t *teacher) {
	t.name = "修改以后"
	t.age = 99
	t.sex = 0
	printTeacher(*t)
}

将结构体作为返回值

func testClass6(t teacher) teacher {
	t.name = "修改以后"
	t.age = 99
	t.sex = 0
	return t
}

将结构体指针作为返回值

func testClass7(t teacher) *teacher {
	t.name = "修改以后"
	t.age = 99
	t.sex = 0
	return &t
}

 

匿名结构体
没有名字的结构体。
无需通过type关键字定义就能直接使用。
在创建匿名结构体时,同时需要创建对象。
匿名结构体由结构体定义和兼职对初始化两个部分组成。
一般情况下匿名结构体仅仅只使用1次。
语法格式:
变量名 := struct {
    定义成员属性
} { 初始化成员属性 }

匿名结构体示例:

func anonymousStruct1() {
	addr := struct {
		province, city string
	}{"HuBei", "WuHan"}
	fmt.Println(addr) //{HuBei WuHan}
}

匿名字段
结构体中的字段没有名字,只包含一个没有字段名的类型。
如果字段没有名字,那么默认使用类型作为字段名。
同一个类型只能写一个,局限性比较强。
结构体嵌套中采用的匿名结构体字段可以模拟继承关系。

匿名字段示例:

type cat struct {
	string
	int8
	byte
}

func anonymousVariables1() {
	c1 := cat{"mimi", 5, 0}
	fmt.Println(c1)
	//分别输出
	fmt.Printf("名字:%v , 年龄:%v ,性别:%v \n", c1.string, c1.int8, c1.byte)
}

 

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 在 Go 语言中,可以使用匿名结构体来定义一个没有名字的结构体类型。匿名结构体没有名字,只有字段,因此可以被用于一些临时性的数据结构或者只用一次的数据结构,可以减少代码的冗余度。 匿名结构体的定义方式和普通结构体类似,只是去掉了结构体的名称,例如: ``` var person struct { name string age int } person.name = "Tom" person.age = 18 ``` 在上面的例子中,我们定义了一个匿名结构体 person,并给它添加了两个字段 name 和 age。可以通过点号来访问结构体中的字段。 使用匿名结构体的好处是可以直接使用一个结构体类型而不需要定义结构体名称,从而简化代码。但是需要注意的是,匿名结构体不能被其他代码引用,因此只能在当前作用域内使用。同时,由于没有结构体名称,也不能像普通结构体一样定义方法。 ### 回答2: Golang中的匿名结构体是指在定义结构体变量时,省略结构体类型名称的方式。具体而言,我们可以在一个结构体内部直接定义另一个结构体,并在定义变量时直接使用该结构体字段匿名结构体的语法形式为: ``` variable := struct { // 字段定义 }{ // 字段赋值 } ``` 这样,我们就可以在一个结构体内部定义并使用另一个结构体,而不需要为其指定一个具体的类型名称。匿名结构体的主要优点在于其灵活性和简洁性,适用于一些临时或者不需要重复使用的结构体。 值得注意的是,由于匿名结构体没有类型名称,因此它无法被其他函数访问或者重新使用。所以,匿名结构体主要用于一些局部的或者只需暂时使用的情况。 下面是一个例子来演示匿名结构体的使用: ``` package main import "fmt" func main() { user := struct { name string age int email string }{ name: "Alice", age: 20, email: "alice@example.com", } fmt.Println(user) } ``` 在上面的例子中,我们定义了一个匿名结构体,并直接在变量`user`的定义中初始化了该结构体字段。然后,我们打印`user`的内容,就可以看到它的字段值。 总而言之,Golang中的匿名结构体可以在一个结构体内部定义并直接使用另一个结构体,具有灵活和简洁的特点,适用于一些临时或者不需要重复使用的场景。 ### 回答3: Golang中的匿名结构体是一种特殊的结构体类型,它不需要定义结构体的名称,直接定义结构体字段和方法。 使用匿名结构体可以快速创建一个临时的结构体对象,无需定义结构体名称。例如: ```go package main import "fmt" func main() { p := struct { name string age int }{ name: "Alice", age: 20, } fmt.Println(p) } ``` 上面的代码中,我们创建了一个匿名结构体对象 `p`,它包含了 `name` 和 `age` 两个字段,并进行了初始化。我们可以直接通过 `p.name` 和 `p.age` 访问这两个字段的值。 匿名结构体通常用于临时的数据需求,避免定义一个独立的结构体类型。它可以直观地表示数据的结构,提高代码的可读性,并且无需关心结构体名称的重复问题。 对于匿名结构体,如果需要在多个地方复用,可以使用定义类型别名的方式。 ```go package main import "fmt" type Person struct { name string age int } func main() { p := struct { Person gender string }{ Person: Person{ name: "Bob", age: 25, }, gender: "Male", } fmt.Println(p) } ``` 上面的代码中,我们定义了一个 `Person` 结构体,并在匿名结构体中嵌入了这个结构体类型。这样一来,就可以在匿名结构体中访问到 `Person` 结构体字段与方法。 总而言之,Golang中的匿名结构体是一种非常方便的临时数据结构,适用于不需要在其他地方复用的情况。它可以直接定义结构体字段和方法,并进行初始化,提高代码的可读性和简洁性。如有需要进行复用,可以使用定义类型别名的方式。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值