new() และกรณีที่ควรใช้พอยน์เตอร์
การจัดสรรด้วย new และรูปแบบการใช้พอยน์เตอร์ที่พบบ่อย
new() และกรณีที่ควรใช้พอยน์เตอร์ เป็นบทเรียน Go Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Go Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Go Academy มีบทเรียนทั้งหมด 4 บทเรียน
ฟังก์ชันในตัว new()
new(T) จัดสรรค่า T ที่ถูกกำหนดเป็นศูนย์ทั้งหมดและคืนค่าเป็น *T สำหรับโครงสร้าง จะเทียบเท่ากับ &T{}:
package main
import "fmt"
func main() {
p := new(int)
fmt.Println(*p) // 0
*p = 42
fmt.Println(*p) // 42
type Point struct{ X, Y int }
pt := new(Point)
fmt.Println(*pt) // {0 0}
}new กับ &T{}
สำหรับโครงสร้าง &T{} เป็นรูปแบบที่สอดคล้องกับแนวทางของ Go มากกว่า และอนุญาตให้กำหนดค่าเริ่มต้นให้ฟิลด์ได้ โดยทั่วไป Go สมัยใหม่แทบไม่ใช้ new:
package main
import "fmt"
type Config struct{ Port int; Host string }
func main() {
a := new(Config) // zeroed
b := &Config{Port: 8080} // initialized
fmt.Println(a, b)
}เมื่อใดควรคืนค่าพอยน์เตอร์
คืนค่าพอยน์เตอร์จากฟังก์ชันสร้างเมื่อ:
- โครงสร้างมีสถานะและผู้เรียกต้องใช้ข้อมูลอินสแตนซ์เดียวกันร่วมกัน
- โครงสร้างมีเมธอดแบบรีซีฟเวอร์พอยน์เตอร์ ซึ่งจำเป็นต่อการรองรับอินเทอร์เฟซ
- โครงสร้างมีขนาดใหญ่และการคัดลอกจะใช้ทรัพยากรมาก
เมื่อใดควรคืนค่า
คืนค่าเมื่อ:
- ชนิดข้อมูลมีขนาดเล็ก มีเพียงไม่กี่ฟิลด์
- เป็นการกำหนดค่าที่ไม่เปลี่ยนแปลง
- ต้องการให้ชัดเจนว่าผู้เรียกจะได้รับสำเนาที่เป็นอิสระจากกัน
ตัวอย่างเช่น time.Time จะถูกคืนค่าโดยตรง แม้ว่าจะมีเมธอดจำนวนมาก
พอยน์เตอร์ในสไลซ์และแมป
การเก็บพอยน์เตอร์ไว้ในชุดข้อมูลทำให้สามารถใช้การแก้ไขค่าร่วมกันได้:
package main
import "fmt"
type User struct{ Name string; Score int }
func main() {
users := []*User{{"Alice", 0}, {"Bob", 0}}
users[0].Score = 100
fmt.Println(users[0]) // &{Alice 100}
}พอยน์เตอร์ไปยังชนิดพื้นฐานเพื่อรองรับค่าที่ไม่บังคับ
ฟิลด์ชนิด *int หรือ *string สามารถเป็น nil เพื่อหมายถึง "ยังไม่ได้กำหนดค่า" ซึ่งมีประโยชน์สำหรับ JSON ที่ใช้ omitempty หรือคอลัมน์ฐานข้อมูลที่ไม่บังคับ:
package main
import "fmt"
type Profile struct {
Name string
Age *int // nil means not provided
}
func main() {
p := Profile{Name: "Alice"}
fmt.Println(p.Age == nil) // true
age := 30
p.Age = &age
fmt.Println(*p.Age) // 30
}การหลีกเลี่ยงการใช้พอยน์เตอร์พร่ำเพรื่อ
การใช้พอยน์เตอร์มากเกินไปเพิ่มภาระให้ GC และลดความเป็นท้องถิ่นของแคช ควรทำการวัดประสิทธิภาพก่อนเปลี่ยนชนิดข้อมูลแบบค่าเป็นพอยน์เตอร์เพียงเพราะเหตุผลด้านประสิทธิภาพ
make กับ new
make เริ่มต้นการทำงานของสไลซ์ แมป และแชนเนล เพราะชนิดข้อมูลเหล่านี้ต้องมีการตั้งค่าภายใน ส่วน new จัดสรรหน่วยความจำที่กำหนดเป็นศูนย์ให้กับชนิดข้อมูลใดก็ได้และคืนค่าพอยน์เตอร์ ทั้งสองอย่างมีจุดประสงค์ต่างกัน:
package main
import "fmt"
func main() {
s := make([]int, 5) // usable slice
m := make(map[string]int) // usable map
p := new(int) // *int pointing to 0
fmt.Println(s, m, *p)
}รูปแบบพอยน์เตอร์ที่ไม่เปลี่ยนแปลง
คืนค่า *T แต่ระบุไว้ในเอกสารว่าเป็นค่าที่ไม่เปลี่ยนแปลง ผู้ใช้ไม่ควรแก้ไขค่า รูปแบบนี้พบได้ทั่วไปในออบเจ็กต์การกำหนดค่าที่ใช้ร่วมกันระหว่างกอร์รูทีน
สรุปความปลอดภัยของพอยน์เตอร์
กฎเพื่อความปลอดภัยเมื่อใช้พอยน์เตอร์:
- ตรวจสอบ nil ก่อนยกเลิกการอ้างอิงเสมอ
- อย่าเก็บพอยน์เตอร์ไปยังตัวแปรบนสแต็กไว้นานกว่าอายุการใช้งานของตัวแปรนั้น การวิเคราะห์การหลุดรอดของ Go จะจัดการเรื่องนี้ให้
- อย่าแปลงชนิดของ unsafe.Pointer เว้นแต่จำเป็นอย่างยิ่ง
- ให้คอมไพเลอร์จัดการการเลือกใช้สแต็กหรือฮีป
ตรวจสอบอย่างรวดเร็ว
new(int) คืนค่าอะไร
สรุปทบทวน: new และพอยน์เตอร์
ประเด็นสำคัญ:
new(T)คืนค่า*Tที่ถูกกำหนดเป็นศูนย์ — ไม่ค่อยใช้ ควรเลือก&T{}- คืนค่าเมื่อข้อมูลมีขนาดเล็กหรือไม่เปลี่ยนแปลง ใช้พอยน์เตอร์เมื่อข้อมูลมีสถานะหรือมีขนาดใหญ่
- ฟิลด์ชนิด
*Tทำให้ใช้ nil เพื่อสื่อว่าไม่มีค่าได้ - อย่าใช้พอยน์เตอร์มากเกินไป — GC มีต้นทุน
โจทย์ฝึกปฏิบัติ
สร้างโครงสร้าง Settings ที่มีฟิลด์ชนิด *int สำหรับ MaxConnections เขียนฟังก์ชันที่รับ *Settings และกำหนดค่าเริ่มต้นเฉพาะเมื่อฟิลด์เป็น nil
คำถามที่พบบ่อย
บทเรียน “new() และกรณีที่ควรใช้พอยน์เตอร์” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “new() และกรณีที่ควรใช้พอยน์เตอร์” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Go Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Go Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “new() และกรณีที่ควรใช้พอยน์เตอร์”
การจัดสรรด้วย new และรูปแบบการใช้พอยน์เตอร์ที่พบบ่อย คุณปฏิบัติ Go Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Go Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน Go Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน
บทเรียน “new() และกรณีที่ควรใช้พอยน์เตอร์” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน Go Academy นี้ได้ไหม
ได้ บทเรียน Go Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- พอยน์เตอร์คืออะไร
- พอยน์เตอร์และฟังก์ชัน
- ตัวรับพอยน์เตอร์ในเมธอด
- new() และกรณีที่ควรใช้พอยน์เตอร์