当前位置: 代码迷 >> 综合 >> Go 聚合类型 结构体 struct 可见性
  详细解决方案

Go 聚合类型 结构体 struct 可见性

热度:106   发布时间:2023-09-30 10:17:23.0

在定义结构体或者结构体中的一些字段,这些是否可以在包内和包外访问到。结构体和结构体当中的字段大小写都会影响在包外是否可以访问到。

结构体名称大写:之间在包外调用初始化就行了

  • 结构体名称大写,属性小写(结构体可以在包外访问,但是成员是不可以被访问的,其实这种就是封装)
  • 结构体名称大写,属性大写

结构体名称小写:包外不能初始化,必须调用函数返回结构体来初始化

  • 结构体名称小写,属性大写(如果结构体都是小写,那么为什么还要将属性大写,结构体都不能被包外访问,那这样做有什么意义呢?可以有个函数大写,虽然在外面不能调用这个结构体,但是可以调用这个函数来返回这个结构体)
  • 结构体名称小写,属性小写(函数返回的结构体当中不能访问)
package testtype privateStruct struct {privateAttr stringPublicAttr string
}func NewPrivateStruct(attr1 string,attr2 string) *privateStruct {return &privateStruct{attr1,attr2}
}//对于访问不了的私有成员,可以使用函数来修改并且返回修改过后私有成员变量值,如果获取属性可以使用get函数
func ChangePrivateAttr(p *privateStruct) string{p.privateAttr = p.privateAttr + " value changed"return p.privateAttr
}----------------------------------------func main()  {a := test.NewPrivateStruct("private","public")fmt.Println(test.ChangePrivateAttr(a))
}private value changed

如果是结构体嵌套,那么被嵌套的结构体定义的变量是大写,那么就可以被访问,反之。被嵌套结构体变量的成员变量大写就可以被访问,反之。

如果是嵌套了匿名结构体,只要调用的时候,包后面的名称都是大写就可以访问,只要包含一个小写就不能访问。(名称可能是结构体名称或者成员名称,其中有一个小写就不可以被访问,所以和匿名结构体定义没有关系,只和使用有关系,使用的时候首字母都是大写,那么就可以访问,有一个首字母小写那么就不可以访问,不需要管里面是如何嵌入的,只需要看在访问的时候看属性大小写)

Go 聚合类型 结构体 struct 可见性

结构体本身的可访问性


不同包结构体本身的可访问性:结构体大写可以被其他包访问到,结构体小写是不能够被其他包访问到。

下面就是在一个包_022_2当中定义一个结构体,Person11大写的时候外部包可以访问到,person11小写的时候外部包不可以访问到。

package _022_2type Person11 struct{Name stringAge int
}package mainimport (_022_2 "2022-2""fmt"
)func main()  {p1 := _022_2.Person11{Name: "lucas",Age: 10}fmt.Println(p1)
}{lucas 0}

如果改为小写是不能够被访问到的

type person11 struct{Name stringAge int
}

结构体变量的成员变量不同包访问:结构体成员变量小写是不能被外部包访问到的。下面这样写是错误的,结构体大写虽然可以访问到,但是由于成员小写是不能被访问到的。

type Person11 struct{name stringAge int
}func main()  {p1 := _022_2.Person11{name: "lucas",Age: 10}fmt.Println(p1)
}

结构体变量到成员变量同包访问:结构体成员大小写都可以同包内被访问到

总结:跨包访问,全局变量,结构体本身,结构体成员变量,必须首字母要大写才可以被访问到。

如果是同包访问,大小写是无所谓的。

这里写了一个方法被别人调用,方法大写,这样可以被其他包调用。age是小写的,在跨包的时候访问不到,但是可以通过大写的方法返回小写的成员变量。

type Person11 struct{Name stringage int
}func (p Person11) GetAge()int{return p.age
}------------------------------------------p1 := _022_2.Person11{Name: "lucas"}fmt.Println("the age is:",p1.GetAge())the age is: 0

最后提一下:全局变量满天飞是一个非常差劲的编码,优秀的代码会非常谨慎的使用全局变量。全局变量会有什么问题呢,在任意一个地方拿到,可能会去修改,可能里面依赖的单测没法写。 

  相关解决方案