ポインタでのC / C ++とは異なり、ポインタのGo言語がシフトすることができないと、操作は安全なポインタです。
アドレスポインタ、ポインタ型、およびポインタ値:移動には次の3つのコンセプトを知っている必要がポインタの言語を理解したいと考えています。
言語のポインタを移動します
行く言語関数のパラメータは、我々は、変数を変更したいとき、我々は変数のアドレスを指すポインタ変数を作成することができ、値をコピーするために渡されます。データをコピーせずに、データポインタを転送します。タイプとポインタのオフセット計算を行うことはできません。:言語のポインタ操作は非常に簡単で行き、2つのだけのシンボル覚えておく必要があります&
(アドレス)、及び*
(アドレス値)。
そして、ポインタ型ポインタアドレス
実行時に、各変数がアドレスを有し、アドレスがメモリ内の可変位置を表します。ゴー言語の使用&
変数の前に置かれた文字変数を操作「フェッチアドレス」。値型(整数、フロート、ブール、文字列 、アレイ、構造体)が移動言語など、対応するポインタの種類があります*int
、*int64
、*string
などが挙げられます。
次のようにポインタ変数構文は取ります:
ptr := &v // v的类型为T
どこで:
- V:変数のアドレスを表す、のタイプであると解釈されます
T
- PTR:変数のアドレスを受信し、それはPTR型で
*T
、ポインタ型Tが呼び出されます。*ポインタを表します。
例えば:
func main() { a := 10 b := &a fmt.Printf("a:%d ptr:%p\n", a, &a) // a:10 ptr:0xc00001a078 fmt.Printf("b:%p type:%T\n", b, b) // b:0xc00001a078 type:*int fmt.Println(&b) // 0xc00000e018 }
のは、見てみましょうb := &a
イラスト:
ポインタ値
&演算子を使用した後、アドレスポインタは次のように、この変数は、次に、ポインタ、すなわちポインタ値*動作のために使用することができ、通常の変数のいずれかを取得する取ります。
func main() { //指针取值 a := 10 b := &a // 取变量a的地址,将指针保存到b中 fmt.Printf("type of b:%T\n", b) c := *b // 指针取值(根据指针去内存取值) fmt.Printf("type of c:%T\n", c) fmt.Printf("value of c:%v\n", c) }
次のように出力されます。
type of b:*int
type of c:int value of c:10
要約:アドレス演算子&
と演算子値*
、相補オペレータのペアである&
フェッチアドレス、*
アドレスが抽出されたアドレス値によって指されます。
次のように変数、特性およびアドレスポインタの関係は、ポインタ変数は、アドレスを取って、値です。
- 変数(&)動作に対処するために取らポインタ変数にこの変数を得ることができます。
- ポインタ変数の値はポインタアドレスです。
- ポインタ変数の値(*)は、元の変数の操作の値は、ポインタ変数のポイントを得ることができます。
例えば値ポインタパス:
func modify1(x int) { x = 100 } func modify2(x *int) { *x = 100 } func main() { a := 10 modify1(a) fmt.Println(a) // 10 modify2(&a) fmt.Println(a) // 100 }
そして新しい作ります
例を見てみましょう:
func main() { var a *int *a = 100 fmt.Println(*a) var b map[string]int b["沙河娜扎"] = 100 fmt.Println(b) }
上記のコードの実装は、なぜ、パニックにつながるのだろうか?参照型の変数の言語に移動し、我々は、使用時にはそれを宣言しなければならないだけでなく、そのためのメモリ空間を割り当てるために、そうでない場合、我々は値を格納する方法がありません。彼らは、宣言の時に割り当てられた適切なデフォルトのメモリ空間を持っているため、ステートメントの型の値については、あなたは、メモリ空間を割り当てる必要はありません。メモリを割り当てるには、それが今日の新しい、作るの外につながります。移動して、新しい言語は主にメモリを割り当てるために使用される2つの組み込み関数、ある作ります。
新しい
次のように新しい組み込み関数、その関数のシグネチャは次のとおりです。
func new(Type) *Type
その中でも、
- タイプはタイプである、新しい関数がパラメータを受け入れ、型を示します
- *タイプは、新しい機能がメモリアドレス型へのポインタを返し、ポインタの型を示します。
あまり一般的で新しい機能は、得られた新しい機能を使用すると、ポインタの種類とポインタの種類に対応するゼロ値の値です。例えば:
func main() { a := new(int) b := new(bool) fmt.Printf("%T\n", a) // *int fmt.Printf("%T\n", b) // *bool fmt.Println(*a) // 0 fmt.Println(*b) // false }
このセクションの最初のサンプルコードでは、var a *int
唯一のポインタ変数を宣言していますが、それに割り当てることができ、後に参照型としてポインタを初期化し、メモリ空間を初期化する必要がありませんでした。次のように初期化のための彼らの割り当て後に正常であることができる新しい組み込み関数を使用する必要があります。
func main() { var a *int a = new(int) *a = 10 fmt.Println(*a) }
作ります
これらの3種類があるので、それは、むしろ彼らのポインタ型に比べ、3型自体で返すも新しいとは異なる、メモリ割り当てのために、のみ使用スライス、マップやメモリちゃんが作成させる、と入力し参照型、アップ自分の手に戻ってする必要はありませんので。関数のシグネチャは、次のような機能を行います。
func make(t Type, size ...IntegerType) Type
作る機能がかけがえのない、我々はスライス、マップやチャンネルを使用し、我々の両方があなたがそれらを操作する前に初期化するようにする必要があります。私たちは前の章で説明してきたこれは、私たちは、以降の章では、チャネルについて詳細に説明します。
始まるこのセクションの例var b map[string]int
だけで変数bを宣言するには、型マップの変数であり、その後、メイク使用初期化関数として、次のサンプルコードのようなものを必要とし、キーと値のペアを割り当てることができます。
func main() { var b map[string]int b = make(map[string]int, 10) b["沙河娜扎"] = 100 fmt.Println(b) }
新規および違いを作ります
- 双方は、メモリ割り当てのために使用されます。
- 唯一のスライス、マップ、チャネル、または基準自体の三種類のリターンを初期化します。
- そして、メモリ割り当て、メモリのタイプとリターンポインタのゼロ値に対応する値の新しいタイプのためのポインタ型です。