跨包的私有字段可訪問性
考慮這樣一種情況:一個包(例如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中文網其他相關文章!