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

Your email address will not be published. Required fields are marked *

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

The reCAPTCHA verification period has expired. Please reload the page.