go语言基础-----06-----匿名字段、同名字段

go语言基础-----06-----匿名字段、同名字段,第1张

一 匿名字段、同名字段 1 匿名字段的作用及其初始化 1)go中的匿名字段就是只有类型,没有名字。2)匿名字段的作用:因为go没有封装、继承、多态的概念,但是go也是可以面向对象编程,因为有匿名字段。例如下面,Student通过匿名字段继承了Persion的所有成员。

实际上学过C的都知道,就是一个简单的结构体嵌套而已,只不过在go叫得高大尚了。

type Persion struct {
	name string
	sex byte
	age int
}

// 普通变量的声明有var关键字,结构体内部不需要var
type Student struct {
	Persion	// 匿名字段,只有类型,没有名字。它继承了Persion的所有成员
	id int
	addr string
}
3)匿名字段的初始化
package main

import "fmt"

type Persion struct {
	name string
	sex byte
	age int
}

// 普通变量的声明有var关键字,结构体内部不需要var
type Student struct {
	Persion	// 匿名字段,只有类型,没有名字。它继承了Persion的所有成员
	id int
	addr string
}

func main(){
	// 1. 顺序初始化
	var s1 Student = Student{Persion{"hh", 'w',24}, 1, "sz"}
	fmt.Println("s1 = ", s1)

	// 2. 自动推导类型
	s2 := Student{Persion{"cc", 'w',24}, 2, "sz"}
	fmt.Printf("s2 = %+v\n", s2)// %+v表示显示更详细

	// 3. 指定成员初始化
	s3 := Student{id:1}
	fmt.Printf("s3 = %+v\n", s3)

	// 这里指定成员赋值时,每个值前面必须手动添加对应的字段名,否则报mixture of field:value and value initializers
	s4 := Student{Persion: Persion{name: "ll", sex: 'w'}, id: 1}
	//s4 := Student{Persion{"cc", 'w'}, 2}// err:mixture of field:value and value initializers
	fmt.Printf("s4 = %+v\n", s4)

	// 4. 使用成员 *** 作来指定成员初始化
	var s5 Student
	s5.Persion.name = "qq"	// 此时写成s5.name是一样的
	s5.name = "mm"
	s5.age = 24
	s5.id = 1
	fmt.Printf("s5 = %+v\n", s5)
}

结果:

2 同名字段

1)同名字段就是在匿名字段中有一个成员,而匿名字段外也有一个同样名字的成员。

type Persion struct {
	name string
	sex byte
	age int
}

// 普通变量的声明有var关键字,结构体内部不需要var
type Student struct {
	Persion	// 匿名字段,只有类型,没有名字。它继承了Persion的所有成员
	id int
	addr string
	name string // 同名字段,因为Persion里面也有一个name。编译器依照就近原则去 *** 作,即本成员优先级高。
}
2)当存在同名字段时,编译器会按照就近原则去搜索。如果在本作用域找到,则直接使用,没有则去继承的结构体中找。
package main

import "fmt"

type Persion struct {
	name string
	sex byte
	age int
}

// 普通变量的声明有var关键字,结构体内部不需要var
type Student struct {
	Persion	// 匿名字段,只有类型,没有名字。它继承了Persion的所有成员
	id int
	addr string
	name string // 同名字段,因为Persion里面也有一个name。编译器依照就近原则去 *** 作,即本成员优先级高。
}

func main(){
	var s1 Student
	s1.name = "hh"				//  *** 作的是Student的name,而不是Persion的name
	s1.id = 1
	s1.addr = "sz"
	s1.Persion.name = "perName"	// 需要显示 *** 作才行
	s1.Persion.age = 22
	s1.Persion.sex = 'w'		// ascii码值打印字符类型
	fmt.Printf("s1 = %+v\n", s1)
}

3 非结构体类型匿名字段 1)实际上非结构体类型匿名字段和第1点讲到的匿名字段是一样的,只不过这些类型不是结构体,一般是基本数据类型,例如int、short这些。
这里只是为了让大家加深印象。
package main

import "fmt"

type Persion struct {
	name string
	sex byte
	age int
}

// 普通变量的声明有var关键字,结构体内部不需要var
type Student struct {
	Persion	// 匿名字段,只有类型,没有名字。它继承了Persion的所有成员
	int
	// string // 不能有同类型的匿名字段,会报错error: duplicate field string
	string // 同名字段,因为Persion里面也有一个name。编译器依照就近原则去 *** 作,即本成员优先级高。
}

func main(){
	var s1 Student
	s1 = Student{Persion{"h", 'w', 24}, 111, "hhh"}
	fmt.Println("s1 = ", s1)
}

4 结构体指针匿名字段 1)同理,结构体指针匿名字段和第1点讲的一样,这里只是让大家加深印象,指定怎么用。
package main

import "fmt"

type Persion struct {
	name string
	sex byte
	age int
}

// 普通变量的声明有var关键字,结构体内部不需要var
type Student struct {
	*Persion	// 匿名字段,只有类型,没有名字。它继承了Persion的所有成员
	id int
	addr string
}

func main(){
	// 1. 不使用new的方式
	s1 := Student{&Persion{"hh", 'w', 24}, 1, "sz"}
	fmt.Println(s1.name, s1.sex, s1.age, s1.id, s1.addr)

	// 2. 使用new的方式
	var s2 Student
	s2.Persion = new(Persion)
	s2.name = "cc"
	s2.sex = 'w'
	s2.age = 24
	s2.id= 1
	s2.addr = "sz"
	fmt.Println(s2.name, s2.sex, s2.age, s2.id, s2.addr)
}

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/995568.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-21
下一篇 2022-05-21

发表评论

登录后才能评论

评论列表(0条)

保存