Array Slice Map เวลาสร้างขึ้นมาจะถือว่าเป็น Reference type โดยอัตโนมัติ ผมจะแสดงให้เห็นผ่านตัวอย่างต่างๆ พร้อมวิธีรับมือครับ
Array
arr := [3]int{0,1,2}
Slice
sli := []int{0,1,2}
Map
m := map[string]bool{
"1": true,
"2": true,
"3": true,
}
โดย Array Slice Map เวลาสร้างขึ้นมาจะถือว่าเป็น Referecne type โดยอัตโนมัติ ผมจะแสดงให้เห็นผ่านตัวอย่างต่างๆ พร้อมวิธีรับมือครับ
เรามาเริ่มต้นกับตัวอย่างด้วย slice
, array
กัน
before := []string{
"apple",
"banana",
"cherry",
}
fmt.Println("Before: ", before)
/* Before: [apple banana cherry] */
after := before
before[0] = "__imposter__"
fmt.Println("After: ", after)
/* After: [__imposter__ banana cherry] */
ผลลัพธ์เมื่อรันโปรแกรม
Before: [apple banana cherry]
After: [__imposter__ banana cherry]
เราจะเห็นได้ว่าแม้ว่าเราจะกำหนดค่าตัวแปร before
มาเป็น after
แล้วก็ตาม
แต่เมื่อเปลี่ยนค่าผ่านตัวแปร before[0]
เป็น __imposter__
ค่าของตัวแปร after
ได้ถูกเปลี่ยนตามไปด้วย
before[0] = "__imposter__"
fmt.Println("After: ", after)
/* After: [__imposter__ banana cherry] */
เรามาทดลองกันอีกสักหน่อย
package main
import "fmt"
func main() {
before := []string{
"apple",
"banana",
"cherry",
}
fmt.Println("before: ", before)
/*before: [apple banana cherry]*/
after := before
UpdateSlice(before)
fmt.Println("after: ", after)
/*after: [__imposter__ banana cherry]*/
}
func UpdateSlice(v []string) {
if len(v) <= 0 {
return
}
v[0] = "__imposter__"
}
สังเกตุว่า UpdateSlice(before)
เมื่อเราส่งค่า before
ไปเปลี่ยนค่าผ่าน function UpdateSlice
แต่ผลลัพธ์ที่ได้ของตัวแปร after
มีการเปลี่ยนไป ถึงแม้ว่าจะไม่ส่งแบบ pointer ก็ตาม
วิธีรับมือ
เราสามารถรับมือได้ด้วน build-in function ที่ชื่อว่า copy
ครับ
copy(destination, source)
ตัวอย่าง
before := []string{
"apple",
"banana",
"cherry",
}
fmt.Println("Before: ", before)
/* Before: [apple banana cherry] */
after := make([]string, len(before))
copy(after, before)
before[0] = "__imposter__"
fmt.Println("After: ", after)
/* After: [apple banana cherry] */
แค่นี้ค่าของตัวแปร after
ก็จะถูกเเยกจากกับตัวแปร before
เดิมเรียบร้อยครับ 🎉🎉🎉
เรามาดูตัวอย่าง Map กันบ้าง
before := map[string]bool{
"apple": true,
"banana": true,
"cherry": true,
}
after := before
before["apple"] = false
for k, v := range after {
fmt.Printf("%v:\t %v\n", k, v)
}
ผลลัพธ์ที่ได้ ซึ่งเราจะเจอเหตุการณ์ที่คล้ายกัน คือ key apple
ของ ตัวแปร after
ถูกเปลี่ยนเป็น false
apple: false
banana: true
cherry: true
วิธีรับมือ
เราสามารถใช้ function ที่ชื่อว่า maps.Clone(source)
maps.Clone(source)
before := map[string]bool{
"apple": true,
"banana": true,
"cherry": true,
}
after := maps.Clone(before)
before["apple"] = false
for k, v := range after {
fmt.Printf("%v:\t %v\n", k, v)
}
ผลลัพธ์ที่ได้ แค่นี้เราก็รับมือกับปัญหานี่ได้เล้วครับ 🎉🎉🎉
apple: true
banana: true
cherry: true
Top comments (0)