ホームページ  >  記事  >  バックエンド開発  >  golangでポインタ変換を実装する方法

golangでポインタ変換を実装する方法

青灯夜游
青灯夜游オリジナル
2023-01-03 17:44:585027ブラウズ

golang では、unsafe パッケージを使用してポインタ変換を実装し、異なるポインタ型間でメモリ アドレスを変換することで、メモリをより柔軟に操作できます。たとえば、unsafe パッケージの Pointer() 関数は、任意の変数のアドレスをポインタ型に変換したり、ポインタ型を任意のポインタ型に変換したりできます。ポインタ型は、異なるポインタ型間の変換の中間型です。

golangでポインタ変換を実装する方法

このチュートリアルの動作環境: Windows 7 システム、GO バージョン 1.18、Dell G3 コンピューター。

golang では、安全でないパッケージを使用してポインタ変換を実装できます。

Golang のポインタ変換

Golang は、指定されたメモリ アドレスのメモリを直接操作できるようにする安全でないパッケージを提供します。

unsafe パッケージの下には、型 Pointer *ArbitraryType (任意の型のポインタ) の定義があり、GO の型制限をバイパスできる ArbitraryType int

  • 任意のタイプのポインター値 すべてをポインターに変換できます。

  • ポインタは、任意のタイプのポインタ値に変換できます。

  • uintptr はポインタに変換できます。

  • ポインタは uintptr に変換できます。

unsafe.Pointer() 関数を通じて、本質的に整数である変数のメモリ アドレス表現を取得できます。任意の変数のアドレスをポインタ型に変換したり、ポインタ型を任意のポインタ型に変換したりできる、異なるポインタ型間の変換の中間型です。

golangでポインタ変換を実装する方法

ただし、ポインタは演算をサポートしていないため、メモリアドレスに対して加減算を行いたい場合は、uintptr 型に変換する必要があります。

以下では、スライス アドレスを読み取り、メモリ操作を通じてその内容を走査しようとします:

package main

import "fmt"
import "unsafe"

func main() {
	// head = {address, 10, 10}
	// body = [1,2,3,4,5,6,7,8,9,10]
	var s = []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
	var address = (**[10]int)(unsafe.Pointer(&s))
	var len = (*int)(unsafe.Pointer(uintptr(unsafe.Pointer(&s)) + uintptr(8)))
	var cap = (*int)(unsafe.Pointer(uintptr(unsafe.Pointer(&s)) + uintptr(16)))
	fmt.Println(address, *len, *cap)
	var body = **address
	for i := 0; i < 10; i++ {
		fmt.Printf("%d ", body[i])
	}
}
----------
0xc000004460 10 10
1 2 3 4 5 6 7 8 9 10

golangでポインタ変換を実装する方法

上記のコード:

  • unsafe.Pointer(&s) スライス s の基礎となる表現によって表される最初の位置のメモリ アドレス、つまり基礎となる配列のアドレス格納アドレスを取得します。 [10]int)(unsafe .Pointer(&s)) を使用して **[10]int 型のポインタに変換し、**addrss;

    ## を通じて配列に復元します。 unsafe.Pointer(uintptr(unsafe.Pointer( &s)) uintptr(8)) アドレス操作を通じて、長さ
  • のストレージ アドレスを取得し、次に (*int)(unsafe.Pointer(uintptr(unsafe) .Pointer(&s)) uintptr(8))) 長さメモリを int ポインタに変換します。

    最後に *len を通じてスライス長を取得します。

    cap の操作は len と同様です。これについては再度説明しません;

簡単に言うと:

unsafe を通じて、異なるポインタ間でメモリ アドレスを変換できます。型を使用することで、メモリをより柔軟に操作できます;

この実験では、スライスの基礎となるストレージ構造もさらに検証されました;

unsafe は、必要でない場合は慎重に使用する必要があります。メモリを直接操作するのは危険です。すべて;

[関連する推奨事項:

Go ビデオ チュートリアル

プログラミング教育]

以上がgolangでポインタ変換を実装する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。