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