结构体的导出

struct的导出特性

  • 如果struct名称的首字母是小写的,这个struct不会被导出。即使有首字母大写的字段名,字段也不会被导出。
  • 如果struct名称的首字母是大写法的,则struct会被导出。但是只会导出内部首字母大写的字段
  • 如果struct嵌套了,那么即使被嵌套在内部的struct名称首字母小写,也能访问到它内部首字母大写的字段
    type animal struct{
        name string
        Speak string
    }
    type Horse struct{
        animal
        sound string
    }
    

不要暴露struct

一般,不讲包中的struct直接暴露给外部,所以struct的名字会以小写字母开头,不将其导出。
外部如果需要创建struct的实例,调用struct的操作,那么就给这个struct编写一个构造函数。

// abc/abc.go文件内容:
package abc

type animal struct{
    name string
    Speak string
}

func NewAnimal() *animal{
    a := new(animal)
    a.name = "ok"
    return a
}


// test.go内容:
package main

import (
    "fmt"
    "./abc"
)

func main() {
    t1 := abc.NewAnimal()
//  t1.name = "haha"    // 无法访问name属性
    t1.Speak = "hhhh"   // 可以访问Speak属性
    fmt.Println(t1.Speak)
}

嵌套struct中的方法导出问题

当内部struct嵌套进外部struct时,内部struct的方法也会被嵌套,也就是说外部struct拥有了内部struct的方法。

但是需要注意方法的首字母大小写问题。由于内、外struct在同一包内,所以直接在该包内构建外部struct实例,外部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 exported
type Admin struct {
    person
    salary int
}

func main() {
    a := new(Admin)
    a.speak()  // 正常输出
    a.Sing()   // 正常输出
}

不同包的struct实例化,不能导出小写方法

package abc

import "fmt"

// 未导出的person
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 exported
type Admin struct {
    person
    salary int
}

// ----------------------
package main

import "./abc"

func main() {
    a := new(abc.Admin)

    // 下面报错
//  a.speak()

    // 下面正常
    a.Sing()
}

参考文献

  1. Go基础系列:struct的导出和暴露问题


blog comments powered by Disqus
—  原创作品许可 — 署名-非商业性使用-禁止演绎 3.0 未本地化版本 — CC BY-NC-ND 3.0   —