Array Slice Map เวลาสร้างขึ้นมาจะถือว่าเป็น Referecne 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 %vn", 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 %vn", k, v) }
ผลลัพธ์ที่ได้ แค่นี้เราก็รับมือกับปัญหานี่ได้เล้วครับ 🎉🎉🎉
apple: true banana: true cherry: true
Source: DEV Community.

Leave a Reply