수색…


통사론

  • pointer : = & variable // 변수로부터 포인터를 얻습니다.
  • variable : = * pointer // 포인터에서 변수를 얻습니다.
  • * pointer = value // 포인터를 통해 변수에서 값 설정
  • pointer : = new (Struct) // 새로운 struct의 포인터를 얻는다.

기본 포인터

Go는 포인터를 지원하므로 프로그램 내의 값과 레코드에 대한 참조를 전달할 수 있습니다.

package main

import "fmt"

// We'll show how pointers work in contrast to values with
// 2 functions: `zeroval` and `zeroptr`. `zeroval` has an
// `int` parameter, so arguments will be passed to it by
// value. `zeroval` will get a copy of `ival` distinct
// from the one in the calling function.
func zeroval(ival int) {
    ival = 0
}

// `zeroptr` in contrast has an `*int` parameter, meaning
// that it takes an `int` pointer. The `*iptr` code in the
// function body then _dereferences_ the pointer from its
// memory address to the current value at that address.
// Assigning a value to a dereferenced pointer changes the
// value at the referenced address.
func zeroptr(iptr *int) {
    *iptr = 0
}

이러한 함수가 정의되면 다음을 수행 할 수 있습니다.

func main() {
    i := 1
    fmt.Println("initial:", i) // initial: 1

    zeroval(i)
    fmt.Println("zeroval:", i) // zeroval: 1
    // `i` is still equal to 1 because `zeroval` edited
    // a "copy" of `i`, not the original.

    // The `&i` syntax gives the memory address of `i`,
    // i.e. a pointer to `i`. When calling `zeroptr`,
    // it will edit the "original" `i`.
    zeroptr(&i)
    fmt.Println("zeroptr:", i) // zeroptr: 0

    // Pointers can be printed too.
    fmt.Println("pointer:", &i) // pointer: 0x10434114
}

이 코드를 사용해보십시오.

포인터 대 값 방법

포인터 메소드

포인터 메소드는 변수 자체가 포인터가 아니더라도 호출 할 수 있습니다.

Go Spec 에 따르면,

. . . 주소 지정 가능 값을 사용하는 포인터 수신자가있는 비 인터페이스 메소드에 대한 참조는 자동으로 해당 값의 주소를 취합니다. t.Mp(&t).Mp .

이 예제에서 이것을 볼 수 있습니다 :

package main

import "fmt"

type Foo struct {
    Bar int
}

func (f *Foo) Increment() {
    f.Bar += 1
}

func main() {
    var f Foo

    // Calling `f.Increment` is automatically changed to `(&f).Increment` by the compiler.
    f = Foo{}
    fmt.Printf("f.Bar is %d\n", f.Bar)
    f.Increment()
    fmt.Printf("f.Bar is %d\n", f.Bar)
    
    // As you can see, calling `(&f).Increment` directly does the same thing.
    f = Foo{}
    fmt.Printf("f.Bar is %d\n", f.Bar)
    (&f).Increment()
    fmt.Printf("f.Bar is %d\n", f.Bar)
}

그것을해라.

값 방법

포인터 메소드와 마찬가지로 변수 자체가 값이 아니더라도 value 메소드를 호출 할 수 있습니다.

Go Spec 에 따르면,

. . . 포인터를 사용하는 값 ​​수신자가있는 비 인터페이스 메소드에 대한 참조는 자동으로 해당 포인터를 참조 해제합니다. pt.Mv(*pt).Mv .

이 예제에서 이것을 볼 수 있습니다 :

package main

import "fmt"

type Foo struct {
    Bar int
}

func (f Foo) Increment() {
    f.Bar += 1
}

func main() {
    var p *Foo

    // Calling `p.Increment` is automatically changed to `(*p).Increment` by the compiler.
    // (Note that `*p` is going to remain at 0 because a copy of `*p`, and not the original `*p` are being edited)
    p = &Foo{}
    fmt.Printf("(*p).Bar is %d\n", (*p).Bar)
    p.Increment()
    fmt.Printf("(*p).Bar is %d\n", (*p).Bar)
    
    // As you can see, calling `(*p).Increment` directly does the same thing.
    p = &Foo{}
    fmt.Printf("(*p).Bar is %d\n", (*p).Bar)
    (*p).Increment()
    fmt.Printf("(*p).Bar is %d\n", (*p).Bar)
}

그것을해라.


포인터 및 값 방법에 대한 자세한 내용은 방법 값이동 사양 섹션을 방문하거나 포인터 및 값에 대한 유효 이동 섹션을 참조하십시오.


참고 1 : .Bar 와 같은 선택자 앞에 *p&f 를 둘러싼 괄호 ( () )는 그룹화 목적으로 사용되므로 보관해야합니다.

주 2 : 포인터는 메소드의 수신자 일 때 값으로 변환 될 수 있지만 (반대의 경우도 마찬가지 임) 포인터 는 함수 내부의 인수 일 때 자동으로 상호 변환 되지 않습니다 .

역 참조 포인터

포인터 앞에 별표 *를 추가하여 포인터를 역 참조 할 수 있습니다.

package main

import (
    "fmt"
)

type Person struct {
    Name string
}

func main() {
    c := new(Person) // returns pointer
    c.Name = "Catherine"
    fmt.Println(c.Name) // prints: Catherine
    d := c
    d.Name = "Daniel"
    fmt.Println(c.Name) // prints: Daniel
    // Adding an Asterix before a pointer dereferences the pointer
    i := *d
    i.Name = "Ines"
    fmt.Println(c.Name) // prints: Daniel
    fmt.Println(d.Name) // prints: Daniel
    fmt.Println(i.Name) // prints: Ines
}

슬라이스는 배열 세그먼트에 대한 포인터입니다.

조각은 배열의 포인터 이며 세그먼트의 길이와 그 용량입니다. 그들은 포인터로 행동하고, 다른 슬라이스에 값을 할당하면 메모리 주소가 할당됩니다. 조각 값을 다른 값으로 복사 하려면 내장 된 복사 함수 func copy(dst, src []Type) int (복사 된 항목의 양을 반환)를 사용합니다.

package main

import (
    "fmt"
)

func main() {
    x := []byte{'a', 'b', 'c'}
    fmt.Printf("%s", x)       // prints: abc
    y := x
    y[0], y[1], y[2] = 'x', 'y', 'z'
    fmt.Printf("%s", x)       // prints: xyz
    z := make([]byte, len(x))
    // To copy the value to another slice, but 
    // but not the memory address use copy:
    _ = copy(z, x)            // returns count of items copied
    fmt.Printf("%s", z)       // prints: xyz
    z[0], z[1], z[2] = 'a', 'b', 'c'
    fmt.Printf("%s", x)       // prints: xyz
    fmt.Printf("%s", z)       // prints: abc
}

간단한 포인터

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

func main() {
  x := int(1)
  y := int(2)
  // variable addresses
  swap(&x, &y)
  fmt.Println(x, y)
}


Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow