खोज…
वाक्य - विन्यास
- सूचक: = और चर // चर से सूचक मिलता है
- वेरिएबल: = * पॉइंटर // पॉइंटर से वेरिएबल प्राप्त करें
- * पॉइंटर = मान // पॉइंटर के माध्यम से वेरिएबल से सेट वैल्यू
- सूचक: = नया (संरचना) // नई संरचना का सूचक मिलता है
बेसिक पॉइंटर्स
गो, पॉइंटर्स को सपोर्ट करता है, जिससे आप अपने प्रोग्राम के भीतर वैल्यूज़ और रिकॉर्ड्स के संदर्भ पास कर सकते हैं।
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
(&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)
}
मूल्य विधियाँ
इसी तरह सूचक विधियों के लिए, मूल्य विधियों को तब भी कहा जा सकता है, भले ही चर स्वयं एक मूल्य न हो।
Go Spec के अनुसार,
। । । एक पॉइंटर का उपयोग करने वाले एक मूल्य रिसीवर के साथ एक गैर-इंटरफ़ेस विधि का एक संदर्भ स्वचालित रूप से उस सूचक को
pt.Mv
: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: चयनकर्ताओं से पहले *p
&f
आसपास कोष्ठक ( ()
) .Bar
समूहीकरण के उद्देश्यों के लिए हैं, और उन्हें रखा जाना चाहिए।
नोट 2: हालांकि पॉइंटर्स को मूल्यों में परिवर्तित किया जा सकता है (और इसके विपरीत) जब वे एक विधि के लिए रिसीवर होते हैं, तो वे फ़ंक्शन के अंदर तर्क होने पर प्रत्येक के लिए स्वचालित रूप से परिवर्तित नहीं होते हैं।
Dereferencing पॉइंटर्स
एक सूचक से पहले एक तारांकन * जोड़कर बिंदुओं को निष्क्रिय किया जा सकता है ।
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)
}