在下面的测试代码中,我希望同时拥有
mytype
和 doPrivate
方法 private,以便只有 mytype
的成员可以访问它,但不能访问 mypackage
范围内的其他类型函数包。
我可以在 Go 中执行此操作吗?
package mypackage
type mytype struct {
size string
hash uint32
}
func (r *mytype) doPrivate() string {
return r.size
}
func (r *mytype) Do() string {
return doPrivate("dsdsd")
}
字段
size
和 hash
以及 doPrivate
方法应该被封装,并且任何其他类型都不应访问它们。
在 Go 中,以大写字母开头的标识符是从包中导出的,并且可以被声明它的包之外的任何人访问。
如果标识符以小写字母开头,则只能从包内访问它。
如果您需要类型中的成员只能由该类型的成员访问,则需要将该类型及其成员函数放在单独的包中,作为该包中的唯一类型。
这不是 Go 中“隐私”的运作方式:隐私的粒度是包。
如果您真的只想让
mytype
的成员访问某些字段,那么您必须将结构体和函数隔离在它们自己的包中。
但这不是通常的做法。 Go 是否是 OOP 是有争议的,但显然实践并不是像您似乎想要的那样通过结构封装代码。通常,包足够小以保持一致:如果您不想访问包内的字段,请不要访问它们。
您可以使用您希望公开的方法创建一个接口,并且仅在包装到该接口中时才访问该对象。
package main
type mytype struct {
size string
hash uint32
}
// interface for exposed methods
type myinterface interface {
do() string
}
// constructor (optional)
func newMytype(size string, hash uint32) myinterface {
return &mytype{size, hash}
}
func (r *mytype) doPrivate() string {
return r.size
}
func (r *mytype) do() string {
return r.doPrivate()
}
func main() {
// with constructor
t := newMytype("100", 100)
t.do()
// t.doPrivate() // t.doPrivate undefined (type myinterface has no field or method doPrivate)
// without constructor
t2:= myinterface(&mytype{"100", 100})
t2.do()
// t.doPrivate() // t.doPrivate undefined (type myinterface has no field or method doPrivate)doPrivate)
}
你无法在 Go 中执行此操作。可见性仅在每个包级别上。但您可以将包裹分成两份。
在一个模块中可以有任意数量的包。
公共/私人仅适用于一个包。
所有 public 字段、方法和函数均以 uppercase 字符开头。
所有 private 字段、方法和函数均以 lowercase 字符开头。
要将包添加到模块或程序中,只需创建一个小写文件夹并将包名称添加到其中的所有文件即可。这是例子。
./main.go
./foo/foo.go
./foo/MyStruct.go
文件
./foo/foo.go
:
package foo
import "fmt"
func SomePublicFuncInFoo() {
somePrivateFuncInFoo()
}
func somePrivateFuncInFoo() {
fmt.Println("somePrivateFuncInFoo call")
}
文件
./foo/MyStruct.go
:
package foo
import "fmt"
type MyStruct struct {
MyPublicField string // starts with uppercase char
myPrivateField string // starts with lowercase char
}
func NewMyStruct(publicField string, privateField string) *MyStruct {
return &MyStruct{
MyPublicField: publicField,
myPrivateField: privateField,
}
}
func (self *MyStruct) SomePublicMethod() {
self.privateMethod()
}
func (self *MyStruct) privateMethod() {
fmt.Println("MyStruct", self.MyPublicField, self.myPrivateField)
}
文件
./main.go
:
package main
import (
"fmt"
"{your-module-name}/foo" // this line should be added by your IDE
)
func main() {
foo.SomePublicFuncInFoo()
myStruct := foo.NewMyStruct("string1", "string2")
fmt.Println("myStruct.MyPublicField=", myStruct.MyPublicField)
myStruct.SomePublicMethod()
}
您可以在 Go 中拥有私有变量和函数,但诀窍是您根本不在结构中定义它们。将它们绑定到闭包的调用堆栈,并且不返回它们。
package main
import (
"fmt"
)
type mytype struct {
Do func() string
}
func MyType(size string, hash uint32) mytype {
doPrivate := func() string {
return size
}
return mytype{
Do: func() string {
return doPrivate()
},
}
}
func main() {
instance := MyType("100", 100)
fmt.Println(instance.Do())
}