ゴラン:ポインター

10127 ワード

導入


シリーズの第10の部分で、我々はプログラミング(すなわち指針)でおもしろい概念を調べています.それは単純なものだが、本当に強力なコンセプトです.ポインタを使用すると、簡単なもののためにたくさんのコードを書くよりも、簡単にいくつかのことができます.私たちは、宣言、参照、参照、および参照によって通過するいくつかの例のような基本的な概念を、structインスタンスへのポインタとともに調べます.

ポインタ


ポインタは簡単です、それはそれが大きな概念になるだけのユースケースです.ポインタは本当に強力です、彼らは与えられた問題のために不可能に思えるかもしれない多くのことをすることができます.ポインタは変数であるが、整数、文字列、論理値などの値を格納する他の変数とは異なり、ポインタはメモリアドレスを格納する.メモリアドレスは、一般的に変数を保持するメモリ内の任意の有効な場所であり得る.
したがって、ポインタを使用することで、変数のメモリアドレスで遊ぶことができ、変数にアクセスするのではなく、メモリアドレスを直接変数の内容を変更することができます.golangでは、ポインタを格納し、同じ操作を実行する方法があります.

ポインタの宣言


ゴランのポインターを宣言するには* データ型の型の前に参照します.これは、ポインタがどのデータ型を参照しているかを指定する必要があることを意味します.最初に、ポインタ変数は<nil> それはNULLポインタ以外の点です.
package main

import "fmt"

func main() {
    var ptr *int
    fmt.Println(ptr)
}

$ go run pointer.go
<nil>
見ることができるように、整数を参照するポインターはNILに初期化されます.使用済み* データ型の前に、これはどんなことでも*string , *bool , *float64 , など

とポインター


ポインタを宣言した後、ポインタをメモリアドレスに割り当てることができます.使用& またはアンパサンド演算子は変数のメモリアドレスを取得できます.
var n := 34
var a_pointer *int = &n
fmt.Println(a_pointer)
$ go run pointer.go
0xc0000a6080
ここで、ポインタ変数は整数変数のメモリアドレスを格納していることがわかります.ポインタ変数の値を心配しないでください、それはちょうどあなたのマシンのメモリ位置です.だから、我々は& 任意の変数のメモリアドレスにアクセスする.
私たちは* はポインタ変数を宣言するために使用されるが、ポインタを参照するためにも使われる.それで、我々が使用するならば& 変数のメモリアドレスを取得するには、同様に* を返します.どちらも値にアクセスするという点では逆です.
n := 34
var a_pointer *int = &n
fmt.Println(a_pointer)
m := *a_pointer
fmt.Println(m)
$ go run pointer.go
0xc0000a8080
34
ご覧の通り、ポインタ変数に格納されている値にアクセスしました.a_pointer ) を使用して* . ここで、我々が作成した変数m は、指定されたポインタ変数のメモリアドレスに格納されているものである.この場合はint , 何でもいい.
だから、これは*& Golangで働くThe * はポインタ変数の宣言とポインタ変数の参照のために使われ、& 演算子は変数のメモリアドレスへのアクセスに使用されます.
それは基本的にゴランのポインターの概念です.それは簡単です.参照とde参照の単純な概念を使用すると、変数の値のコピーではなく、実際に値を渡すことができるような関数を参照渡しするような操作を行うことができます.

関数への参照渡し


今、我々はポインタの基礎をクリアし、実際にいくつかの本当に便利な操作を行うためにそれらを使用して移動することができます.一般に、整数、文字列、boolなどのパラメータを使用する場合、変数のコピーを変数の実際の値ではなく関数に渡します.これは、ポインターが来るところです.ポインタを使用して、変数のメモリアドレスを渡すことで、実際に変数の場所を渡す必要があります.
つの変数の値をスワップする関数の簡単な例を見てみましょう.
package main

import "fmt"

func swap(x *int, y *int) {
    temp := *x
    *x = *y
    *y = temp
}

func main() {

    x := 3
    y := 6
    k := &x
    p := &y
    fmt.Printf("Before swapping : x = %d and y = %d.\n", x, y)
    swap(k, p)
    fmt.Printf("After swapping  : x = %d and y = %d.\n", x, y)
}
$ go run pointer.go
Before swapping : x = 3 and y = 6.
After swapping  : x = 6 and y = 3.
パラメータの値を関数に渡すためにポインタを使用していることが分かります.ポインタを使用せずに、変数の値はコピーとして渡されますが、ポインタを使用することで、実際にメモリアドレスを渡します.メイン関数では、まず2つの変数のメモリアドレスを格納しますx and y つの異なるポインタ変数に.我々は、現在2つのメモリアドレスを受け入れて、さらなる操作を実行する機能を構築することができます.
関数の内部では、* . 混乱させるなx *int with *x . 使用するx *int 関数を整数値のポインター変数を渡していることを実現するには*x は、x .
だから、簡単に
  • 保存されたメモリの場所に値を格納するx TEMP変数
  • に格納されているメモリアドレスに値を格納するy メモリアドレスにx .
  • temp変数の値を、x .
  • 関数から値を返さずに2つの値をうまくスワップできました.

    structインスタンス/ objectへのポインタ


    現在では、ポインタにインスタンスを参照することで、構造体/インスタンスの値を変更することもできます.ポインタ変数をstructインスタンスに代入することで、関連するプロパティと関数にアクセスできます.これにより、ポインタ変数から直接内容を変更することができます.
    structインスタンスへのポインターを使用してプロパティを変更する基本的な例を見てみましょう.
    package main
    
    import "fmt"
    
    type Book struct {
        pages int
        genre string
        title string
    }
    
    func main() {
        new_book := Book{120, "fiction", "Harry Potter"}
        fmt.Println(new_book)
        fmt.Printf("Type of new_book -> %T\n", new_book)
        book_ptr := &new_book
        book_ptr.title = "Games of Thrones"
        fmt.Println(new_book)
    }
    
    
    $ go run pointer.go
    {120 fiction Harry Potter}
    Type of new_book -> main.Book
    {120 fiction Games of Thrones}
    
    そこで、構造体である型のポインタ変数を作成しましたBook , これは、構造体で定義された様々なプロパティに関連するメモリアドレスへのアクセスを可能にします.ポインタ変数を使用すると、プロパティにアクセスすることができ、それによってbook_ptr . それで、我々が言うならばbook_ptr.title = "Games of Thrones" , 文字列を直接メモリのアドレスに格納しますnew_book オブジェクトとしてbook_ptr structオブジェクトへのメモリアドレスを参照するnew_book .
    ここでは、文字列を使用して、構造体のプロパティの値を文字列で変更しました.これは本当に強力で、時間を節約できます.ポインタが物でないなら、あなたは同じことをするために別々の機能を書かなければなりません.
    それはこの部分からです.すべてのコード例とコマンドの参照は100 days of Golang githubリポジトリ.

    結論


    それで、単純なスクリプトまたはプログラムの作業を理解することができるように、我々はポインタの十分な基礎をカバーしました.スライスや文字列のような単純なデータ構造でも、Golangのポインターを使用することで理解できます.シリーズのこの部分から、我々は機能への参照とstructインスタンスへのポインタを作成することによって通過することとともにポインタの宣言、参照と参照を理解することができました.
    お読みありがとうございます.ご質問やご意見がある場合は、コメントや社会的なハンドルで私に知らせてください.ハッピーコーディング