跨包的私有字段可访问性
考虑这样一种情况:一个包(例如 foo)中定义的结构体包含私有字段和另一个包(例如,酒吧)需要访问它们。不幸的是,Go 的包级封装禁止从外部包直接访问私有字段。
但是,访问这些私有字段的方法有限,尽管有一些注意事项:
使用反射 (Go
在 Go 1.7 之前,它是可以使用反射读取私有字段:
package bar import "../foo" import "fmt" import "reflect" func read_foo(f *foo.Foo) { v := reflect.ValueOf(*f) y := v.FieldByName("y") fmt.Println(y.Interface()) }
这种方法允许检索私有字段值,但不允许对其进行修改。
操作内存(Go >= 1.7)
在 Go 1.7 及更高版本中,一种不太理想的方法是使用不安全指针直接操作内存。通过根据字段大小和偏移量推进内存指针,可以访问私有字段:
package bar import "../foo" import "unsafe" func change_foo(f *foo.Foo) { ptrTof := unsafe.Pointer(f) ptrTof = unsafe.Pointer(uintptr(ptrTof) + uintptr(8)) // Advance by the size of int ptrToy := (**foo.Foo)(ptrTof) *ptrToy = nil }
由于其不可移植性和数据损坏的可能性,强烈建议不要使用此方法。
替代方案
除了直接访问私有字段之外,还有更合适的options:
请记住,封装的目的是维护数据完整性并防止意外修改。如果需要访问私有字段,请仔细考虑是否有更合适的替代方案。
以上是如何跨包访问Go中的私有字段?的详细内容。更多信息请关注PHP中文网其他相关文章!