Sök…


Syntax

  • pekaren: = & variabel // få pekaren från variabeln
  • variabel: = * pekare // få variabel från pekaren
  • * pekare = värde // ställa in värde från variabel genom pekaren
  • pekaren: = ny (struktur) // få pekaren till ny struktur

Grundläggande pekare

Go stöder pekare , så att du kan skicka referenser till värden och poster i ditt program.

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
}

När dessa funktioner har definierats kan du göra följande:

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
}

Prova den här koden

Pointer v. Value Methods

Pekarmetoder

Pekarmetoder kan kallas även om variabeln i sig inte är en pekare.

Enligt Go Spec

. . . en hänvisning till ett icke-gränssnittsmetod med en pekmottagare som använder ett adresserbart värde tar automatiskt adressen till det värdet: t.Mp motsvarar (&t).Mp .

Du kan se detta i detta exempel:

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)
}

Spela den

Värde Metoder

På samma sätt som pekarmetoder, kan värdemetoder kallas även om variabeln i sig inte är ett värde.

Enligt Go Spec

. . . en hänvisning till en metod som inte är gränssnittet med en värdemottagare som använder en pekare kommer automatiskt att eliminera den pekaren: pt.Mv motsvarar (*pt).Mv .

Du kan se detta i detta exempel:

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)
}

Spela den


Om du vill veta mer om pekare- och värdemetoder besöker du Go Spec-avsnittet om Method Values eller se avsnittet Effective Go om Pointers v. Values .


Obs 1: parentesen ( () ) runt *p och &f innan väljare som .Bar finns där för gruppering och måste hållas.

Obs 2: Även om pekare kan konverteras till värden (och vice versa) när de är mottagare för en metod, konverteras de inte automatiskt till varandra när de är argument inuti en funktion.

Dereferencing pekare

Pekare kan avlägsnas genom att lägga till en asterisk * före en pekare.

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
}

Skivor är pekare på array-segment

Skivor är pekare på matriser med segmentets längd och dess kapacitet. De uppför sig som pekare och tilldelar minnesadressen tilldelar deras värde till en annan bit. Om du vill kopiera ett segmentvärde till ett annat använder du den inbyggda kopieringsfunktionen : func copy(dst, src []Type) int (returnerar mängden kopierade objekt).

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
}

Enkla pekare

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
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow