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

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

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

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

パッケージ間のプライベート フィールドへのアクセス

あるパッケージ (foo など) で定義された構造体にプライベート フィールドと別のパッケージが含まれるシナリオを考えてみましょう。 (バーなど) にはアクセスする必要があります。残念ながら、Go のパッケージレベルのカプセル化により、外部パッケージからプライベート フィールドに直接アクセスすることは禁止されています。

ただし、これらのプライベート フィールドにアクセスする方法は限られていますが、次のような注意事項があります。

リフレクション (Go

Go 前1.7 では、リフレクションを使用してプライベート フィールドを読み取ることができました。

1

2

3

4

5

6

7

8

9

10

11

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 以降では、あまり望ましくない方法として、安全でないポインタを使用してメモリを直接操作する。フィールド サイズとオフセットに基づいてメモリ ポインタを進めることにより、プライベート フィールドにアクセスできます:

1

2

3

4

5

6

7

8

9

10

11

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 サイトの他の関連記事を参照してください。

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