ホームページ > バックエンド開発 > Golang > 異なるパッケージ間で Go のプライベート フィールドにアクセスするにはどうすればよいですか?

異なるパッケージ間で Go のプライベート フィールドにアクセスするにはどうすればよいですか?

Linda Hamilton
リリース: 2024-12-24 18:37:14
オリジナル
579 人が閲覧しました

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
}
ログイン後にコピー

この方法は、移植性がなく、データ破損の可能性があるため、非常に推奨されません。

代替ソリューション

プライベート フィールドに直接アクセスする代わりに、より適切な解決策があります。オプション:

  • フィールド アクセスが必要なロジックを構造体と同じパッケージに移動します。
  • プライベート フィールドへの制御されたアクセスを提供する安全なインターフェイスまたはメソッドをエクスポートします。
  • 同じテスト内のプライベート フィールドへのアクセスを可能にするために、ホワイトボックス テストの使用を検討してください (テストに _test.go という名前を付けます)。 package.

カプセル化の目的は、データの整合性を維持し、意図しない変更を防ぐことであることに注意してください。プライベート フィールドにアクセスする必要がある場合は、より適切な代替手段があるかどうかを慎重に検討してください。

以上が異なるパッケージ間で Go のプライベート フィールドにアクセスするにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート