@جوزيعلی جوزی
باز هم مهندس نرم افزار دیگری
اینها اشتباهاتی است که من نوشتن Go را مرتکب شده ام. اگرچه اینها ممکن است نباشد
هر نوع خطایی ایجاد می کند اما به طور بالقوه می تواند بر روی نرم افزار تأثیر بگذارد.
روش های مختلفی برای ایجاد یک ظرف غذا در داخل یک حلقه وجود دارد که باید از آنها آگاه باشید.
1.1 استفاده از ارجاع به متغیر تکرار کننده حلقه
به دلیل کارایی ، متغیر تکرار کننده حلقه یک متغیر واحد است
مقادیر مختلفی را در هر تکرار حلقه می گیرد. این ممکن است منجر به یک رفتار ناخواسته شود.
in := []int{1, 2, 3}
var out []*int
for _, v := range in {
out = append(out, &v)
}
fmt.Println("Values:", *out[0], *out[1], *out[2])
fmt.Println("Addresses:", out[0], out[1], out[2])
نتیجه این خواهد بود:
Values: 3 3 3
Addresses: 0xc000014188 0xc000014188 0xc000014188
همانطور که می توانید تمام عناصر را در مشاهده کنید
out
slice 3 هستند. در واقع توضیح اینکه چرا این اتفاق افتاده آسان است: در هر تکرار آدرس آدرس را ضمیمه می کنیم
v
به
out
تکه. همانطور که قبلا ذکر شد
v
یک متغیر واحد است که مقادیر جدیدی را در هر تکرار می گیرد. بنابراین همانطور که در خط دوم خروجی مشاهده می کنید ، آدرس ها یکسان هستند و همه آنها به یک مقدار اشاره می کنند.
راه حل ساده این است که متغیر تکرار کننده حلقه را در یک متغیر جدید کپی کنید:
in := []int{1, 2, 3}
var out []*int
for _, v := range in {
v := v
out = append(out, &v)
}
fmt.Println("Values:",...