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为第一个定位点。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值