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语言学习笔记 — 基础 — 复合数据类型 — 结构体:构造函数 — 封装结构体和类型的一系列初始化操作(封装数据)

go语言学习笔记 — 基础 — 复合数据类型 — 结构体(10.2):自定义设置隐藏的成员属性,并获取它的值

go语言学习笔记 — 基础 — 复合数据类型 — 结构体(10.1):隐藏结构体与跨包引用结构体