Pointers और Values: कब क्या Use करें
func modify(v *TypeName) { // pointer: can change the caller's value
v.field = newValue
}
func read(v TypeName) { // value: gets a copy
// use v
}
modify(&value)
read(value)
When Mutation Is Needed
अगर किसी function या method को caller का original data बदलना है, इसे एक pointer लेना चाहिए -- value से पास करना हमेशा सिर्फ एक copy पर operate करता है, इसलिए function के return होते ही कोई भी बदलाव खो जाता है।
उदाहरण: When Mutation Is Needed
// Every Go file belongs to a package; main builds an executable
package main
// Import the fmt package
import "fmt"
// Define a struct type named Account
type Account struct {
Balance float64
}
// Define the method Withdraw on type Account
func (a *Account) Withdraw(amount float64) {
a.Balance -= amount
}
// main is where the program starts running
func main() {
// Short declaration: create acc and infer the type
acc := Account{Balance: 200}
acc.Withdraw(50)
// Print the values followed by a newline
fmt.Println(acc.Balance)
}
Login to try C/C++/Java/PHP code in the editor
When Copying Is Fine
छोटी, साधारण values के लिए -- जैसे दो ints वाला एक Point -- copying सस्ती है और अक्सर code के बारे में सोचना आसान बना देती है, क्योंकि caller को shared pointer के ज़रिए अनपेक्षित mutation की चिंता नहीं करनी पड़ती।
उदाहरण: When Copying Is Fine
// Every Go file belongs to a package; main builds an executable
package main
// Import the fmt package
import "fmt"
// Define a struct type named Point
type Point struct {
X, Y int
}
// Define the function translate
func translate(p Point, dx, dy int) Point {
return Point{X: p.X + dx, Y: p.Y + dy}
}
// main is where the program starts running
func main() {
// Short declaration: create original and infer the type
original := Point{1, 1}
// Short declaration: create moved and infer the type
moved := translate(original, 2, 3)
// Print the values followed by a newline
fmt.Println("original:", original, "moved:", moved)
}
Login to try C/C++/Java/PHP code in the editor
Avoiding Copies of Large Structs
कई fields वाले एक struct के लिए, इसे value से पास करना हर function call पर हर field copy करता है, जो hot code paths में जुड़ जाता है -- इसके बजाय एक pointer पास करना उस copying cost से बचाता है, mutable state share करने की कीमत पर।
उदाहरण: Avoiding Copies of Large Structs
// Every Go file belongs to a package; main builds an executable
package main
// Import the fmt package
import "fmt"
// Define a struct type named Report
type Report struct {
Title string
Lines []string
Total float64
}
// Define the function summarize
func summarize(r *Report) string {
// Sprintf builds a formatted string instead of printing it
return fmt.Sprintf("%s: %d lines, total %.2f", r.Title, len(r.Lines), r.Total)
}
// main is where the program starts running
func main() {
// Short declaration: create r and infer the type
r := &Report{Title: "Sales", Lines: []string{"a", "b"}, Total: 99.5}
// Print the values followed by a newline
fmt.Println(summarize(r))
}
Login to try C/C++/Java/PHP code in the editor
- छोटे structs पर performance के लिए हर जगह default रूप से pointers उपयोग करना, जब एक छोटी value copy करना अक्सर उतना ही तेज़ और सोचने में सरल होता है।
- एक ही type के methods में असंगत रूप से value और pointer receivers मिलाना, जो interfaces के साथ भ्रामक behavior का कारण बन सकता है।
- किसी hot loop में एक बड़े struct को value से पास करना, अनावश्यक copying overhead का कारण बनते हुए जिसे एक pointer टाल देता।
- एक pointer उपयोग करें जब किसी function को caller की original value modify करनी हो।
- बड़े structs copy करने से बचने के लिए एक pointer उपयोग करें, performance सुधारते हुए।
- छोटे, साधारण data के लिए एक साधारण value उपयोग करें जहां mutation की ज़रूरत न हो -- इसके बारे में सोचना सरल है।
- किसी एक type के methods में receiver types को consistent रखें, किसी भी method को mutate करना हो तो pointer receivers को प्राथमिकता दें।
Chapter Quiz — Complete all 6 topics to unlock
0/6 topics done
Complete these topics first: