go语言学习笔记 — 基础 — 复合数据类型 — 结构体(9.2):结构体可见性规则,外层结构体实例访问嵌套结构体中内层结构体的方法(重要)
Posted Locutus
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了go语言学习笔记 — 基础 — 复合数据类型 — 结构体(9.2):结构体可见性规则,外层结构体实例访问嵌套结构体中内层结构体的方法(重要)相关的知识,希望对你有一定的参考价值。
当内层struct嵌套进外层struct时,内层struct的方法也会被嵌套,也就是说外层struct拥有了内层struct的方法。
需要注意的是,方法的首字母大小写。由于内、外层struct在同一个包内,所以直接在包内构建外层struct实例时,外部struct实例可以直接访问内部struct的所有方法;但如果在不同包内构建外部struct实例,外部struct实例将无法访问内部struct中首字母小写的方法。
1. 同一个包内测试
由于内、外struct在同一包内,所以直接在包内构建外层struct实例,外层struct实例可以直接访问内层struct的所有方法。
- 同一文件内测试(重要)
package main
import (
"fmt"
)
type person struct {
name string
age int
}
// 小写方法,未暴露
func (p *person) speak() {
fmt.Println("speak in person")
}
// 大写方法,暴露
func (p *person) Sing() {
fmt.Println("Sing in person")
}
// 结构体Admin嵌套person
type Admin struct {
person
salary int
}
func main() {
a := new(Admin)
a.speak() // 正常输出
a.Sing() // 正常输出
}
- 不同文件内测试(重要)
# tree .
.
├── abc.go
├── test.go
main.go
package main
func main() {
a := new(Admin)
a.speak() // 正常输出
a.Sing() // 正常输出
}
test.go
package main
import (
"fmt"
)
type person struct {
name string
age int
}
// 未暴露的方法,小写
func (p *person) speak() {
fmt.Println("speak in person")
}
// 暴露的方法,大写
func (p *person) Sing() {
fmt.Println("Sing in person")
}
// 结构体Admin嵌套person
type Admin struct {
person
salary int
}
# go run main.go test.go
speak in person
Sing in person
如果不加后边的test.go,那么会报错#command-line-arguments ./main.go:5:14:undefined:Admin,因为main.go会依赖test.go中的Admin结构体。
注:对多个包存在引用关系,或者引用的包对当前目录的其他文件存在引用,也都是一样的方法,把依赖go源文件加在命令后方即可。
2. 不同包内测试(重要)
在不同包内构建外部struct实例,外部struct实例将无法访问内部struct中首字母小写的方法。
目录结构
# tree
.
├── abc
│ └── type.go
└── main.go
struct定义在库文件abc/type.go中
package abc
import (
"fmt"
)
type person struct {
name string
age int
}
// 小写方法,未暴露
func (p *person) speak() {
fmt.Println("speak in person")
}
// 大写方法,暴露
func (p *person) Sing() {
fmt.Println("Sing in person")
}
// 结构体Admin嵌套person
type Admin struct {
person
salary int
}
主函数main在主文件main.go中
package main
import (
"./abc" // 包相对导入
)
func main() {
a := new(abc.Admin) // 导入abc包下的Admin类型
// 调用报错,a.speak undefined (type *abc.Admin has no field or method speak)
// a.speak()
// 调用正常
a.Sing()
}
注:相对导入的资源,以资源所在的包为第一个定位点。如abc.Admin,资源Admin,包abc为第一个定位点。
以上是关于go语言学习笔记 — 基础 — 复合数据类型 — 结构体(9.2):结构体可见性规则,外层结构体实例访问嵌套结构体中内层结构体的方法(重要)的主要内容,如果未能解决你的问题,请参考以下文章
go语言学习笔记 — 基础 — 复合数据类型 — 结构体:使用匿名结构体分离json数据
go语言学习笔记 — 基础 — 复合数据类型 — 结构体:如何在包中引用另外一个包的结构体?
go语言学习笔记 — 基础 — 复合数据类型 — 结构体:类型内嵌与结构体内嵌(扩展和复用)
go语言学习笔记 — 基础 — 复合数据类型 — 结构体:构造函数 — 封装结构体和类型的一系列初始化操作(封装数据)