首頁 > 後端開發 > Golang > 如何跨包存取Go中的私有欄位?

如何跨包存取Go中的私有欄位?

Linda Hamilton
發布: 2024-12-24 18:37:14
原創
619 人瀏覽過

How Can I Access Private Fields in Go Across Different Packages?

跨包的私有字段可訪問性

考慮這樣一種情況:一個包(例如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:

  • 將需要欄位存取的邏輯移至與結構相同的包中。
  • 匯出提供對私有欄位的受控存取的安全介面或方法。
  • 考慮使用白盒測試(透過將測試命名為_test.go)來允許存取相同測試中的私有欄位package.

請記住,封裝的目的是維護資料完整性並防止意外修改。如果需要存取私有字段,請仔細考慮是否有更合適的替代方案。

以上是如何跨包存取Go中的私有欄位?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板