The Go ภาษาสเปกสินค้า ( ผู้ประกอบการที่อยู่ ) ไม่อนุญาตให้ใช้ที่อยู่ของตัวเลขคงที่ (ไม่นั้นuntypedมิได้ของพิมพ์คงที่)
ตัวถูกดำเนินการจะต้องระบุแอดเดรสได้นั่นคือตัวแปรการชี้ทิศทางของตัวชี้หรือการดำเนินการจัดทำดัชนีสไลซ์ หรือตัวเลือกฟิลด์ของตัวดำเนินการโครงสร้างแอดเดรส หรือการดำเนินการจัดทำดัชนีอาร์เรย์ของอาร์เรย์แอดเดรส ยกเว้นข้อกำหนดความสามารถในการระบุตำแหน่งx
[ในนิพจน์&x
] อาจเป็นตัวอักษรผสม (อาจเป็นวงเล็บ) ก็ได้
สำหรับเหตุผลว่าทำไมถึงไม่ได้รับอนุญาตให้ดูคำถามที่เกี่ยวข้อง: ค้นหาที่อยู่ของอย่างต่อเนื่องในการเดินทาง คำถามที่คล้ายกัน (ไม่อนุญาตให้ใช้ที่อยู่ในทำนองเดียวกัน): ฉันจะจัดเก็บข้อมูลอ้างอิงถึงผลลัพธ์ของการดำเนินการใน Go ได้อย่างไร?
ตัวเลือกของคุณ (ลองทั้งหมดบนGo Playground ):
1) ด้วย new()
คุณสามารถใช้new()
ฟังก์ชันbuiltin เพื่อจัดสรรค่าศูนย์ใหม่int64
และรับที่อยู่:
instance := SomeType{
SomeField: new(int64),
}
แต่โปรดทราบว่าสิ่งนี้สามารถใช้เพื่อจัดสรรและรับตัวชี้ไปที่ค่าศูนย์ของประเภทใดก็ได้เท่านั้น
2) ด้วยตัวแปรตัวช่วย
ง่ายที่สุดและแนะนำสำหรับองค์ประกอบที่ไม่ใช่ศูนย์คือการใช้ตัวแปรตัวช่วยที่สามารถรับแอดเดรสได้:
helper := int64(2)
instance2 := SomeType{
SomeField: &helper,
}
3) ด้วยฟังก์ชันตัวช่วย
หมายเหตุ:ฟังก์ชันตัวช่วยในการรับตัวชี้ไปยังค่าที่ไม่ใช่ศูนย์มีอยู่ในgithub.com/icza/gox
ไลบรารีของฉันในgox
แพ็กเกจดังนั้นคุณไม่จำเป็นต้องเพิ่มสิ่งเหล่านี้ในโปรเจ็กต์ทั้งหมดที่คุณต้องการ
หรือถ้าคุณต้องการหลาย ๆ ครั้งคุณสามารถสร้างฟังก์ชันตัวช่วยซึ่งจัดสรรและส่งคืน*int64
:
func create(x int64) *int64 {
return &x
}
และใช้มัน:
instance3 := SomeType{
SomeField: create(3),
}
โปรดทราบว่าเราไม่ได้จัดสรรอะไรเลยคอมไพเลอร์ Go ทำเช่นนั้นเมื่อเราส่งคืนที่อยู่ของอาร์กิวเมนต์ของฟังก์ชัน คอมไพเลอร์ Go ทำการวิเคราะห์ Escape และจัดสรรตัวแปรโลคัลบนฮีป (แทนที่จะเป็นสแต็ก) หากพวกเขาอาจหลบหนีฟังก์ชัน สำหรับรายละเอียดโปรดดูที่การส่งคืนส่วนของอาร์เรย์ในเครื่องในฟังก์ชัน Go ปลอดภัยหรือไม่
4) ด้วยฟังก์ชันไม่ระบุชื่อซับเดียว
instance4 := SomeType{
SomeField: func() *int64 { i := int64(4); return &i }(),
}
หรือเป็นทางเลือก (สั้นกว่า):
instance4 := SomeType{
SomeField: func(i int64) *int64 { return &i }(4),
}
5) ด้วยการแบ่งตามตัวอักษรการสร้างดัชนีและการรับที่อยู่
หากคุณต้องการที่*SomeField
จะเป็นอื่นที่ไม่ใช่0
คุณต้องมีสิ่งที่สามารถระบุได้
คุณยังทำได้ แต่น่าเกลียด:
instance5 := SomeType{
SomeField: &[]int64{5}[0],
}
fmt.Println(*instance2.SomeField)
สิ่งที่เกิดขึ้นที่นี่คือส[]int64
ไลซ์ถูกสร้างขึ้นด้วยตัวอักษรโดยมีองค์ประกอบหนึ่ง ( 5
) และมีการจัดทำดัชนี (องค์ประกอบที่ 0) และใช้ที่อยู่ขององค์ประกอบที่ 0 ในพื้นหลังอาร์เรย์ของ[1]int64
จะถูกจัดสรรและใช้เป็นอาร์เรย์สำรองสำหรับสไลซ์ ที่นี่จึงมีแผ่นสำเร็จรูปมากมาย
6) ด้วยตัวช่วยโครงสร้างตามตัวอักษร
มาตรวจสอบข้อยกเว้นของข้อกำหนดความสามารถในการระบุตำแหน่ง:
ยกเว้นข้อกำหนดความสามารถในการระบุตำแหน่งx
[ในนิพจน์&x
] อาจเป็นตัวอักษรผสม (อาจเป็นวงเล็บ) ก็ได้
ซึ่งหมายความว่าการใช้แอดเดรสของตัวอักษรผสมเช่นโครงสร้างลิเทอรัลก็ใช้ได้ ถ้าเราทำเช่นนั้นเราจะมีการจัดสรรค่าโครงสร้างและตัวชี้ที่ได้รับ แต่ถ้าเป็นเช่นนั้นความต้องการอื่นจะกลายเป็นมีให้เรา: "เลือกเขตของตัวถูกดำเนินการ struct แอดเดรส" ดังนั้นหากโครงสร้างลิเทอรัลมีฟิลด์ประเภทint64
เราสามารถใช้แอดเดรสของฟิลด์นั้นได้ด้วย!
ลองดูตัวเลือกนี้ในการดำเนินการ เราจะใช้ประเภทโครงสร้างของ wrapper นี้:
type intwrapper struct {
x int64
}
และตอนนี้เราสามารถทำได้:
instance6 := SomeType{
SomeField: &(&intwrapper{6}).x,
}
โปรดทราบว่าสิ่งนี้
&(&intwrapper{6}).x
หมายถึงสิ่งต่อไปนี้:
& ( (&intwrapper{6}).x )
แต่เราสามารถเว้นวงเล็บ "ด้านนอก" เป็นตัวดำเนินการที่อยู่ได้ &
ถูกนำไปใช้ผลของการแสดงออกทางเลือก
โปรดทราบว่าในเบื้องหลังสิ่งต่อไปนี้จะเกิดขึ้น (นี่เป็นไวยากรณ์ที่ถูกต้องด้วย):
&(*(&intwrapper{6})).x
7) ด้วยตัวช่วยที่ไม่ระบุชื่อโครงสร้างตามตัวอักษร
หลักการนี้เหมือนกับกรณี # 6 แต่เรายังสามารถใช้ตัวอักษรโครงสร้างแบบไม่ระบุตัวตนได้ดังนั้นจึงไม่จำเป็นต้องมีการกำหนดประเภทโครงสร้างตัวช่วย / ตัวห่อ:
instance7 := SomeType{
SomeField: &(&struct{ x int64 }{7}).x,
}