فهم أجهزة استقبال المؤشر ومثيلات النسخ
في Go، يمكن تحديد الطريقة إما باستخدام جهاز استقبال القيمة أو جهاز استقبال المؤشر. عندما تحتوي جميع الطرق من النوع T على نوع جهاز استقبال من T نفسه، فمن الآمن نسخ مثيلات من هذا النوع، حيث أن استدعاء أي من طرقه يؤدي بالضرورة إلى إنشاء نسخة.
ومع ذلك، يتغير الوضع عندما يكون هناك نوع ما لديه أساليب مع جهاز استقبال المؤشر. في هذه الحالة، يجب تجنب نسخ مثيلات من هذا النوع، لأنه قد ينتهك الثوابت الداخلية.
مشكلة نسخ المؤشرات
دعونا نفكر في مثال لتوضيح مشكلة. لنفترض أن لدينا نوع غلاف يحتوي على حقلين: القيمة v والمؤشر p. نعتزم تخزين نفس الرقم في كل من v والقيمة المشار إليها لـ p. لضمان ذلك، نوفر طريقة Set مع مستقبل المؤشر:type Wrapper struct {
v int
p *int
}
func (w *Wrapper) Set(v int) {
w.v = v
*w.p = v
}
إذا كان لدينا مثيل لـ Wrapper وقمنا باستدعاء طريقة Set، فسيتم تعديل القيمة المشار إليها لـ p. ومع ذلك، إذا قمنا بإنشاء نسخة من المثيل، فستشارك النسخة نفس قيمة المؤشر p مثل المثيل الأصلي. وهذا يعني أن أي استدعاءات أسلوب لاحقة على أي من المثيلين ستؤثر على كلا النسختين.مثال:
a := Wrapper{v: 0, p: new(int)}
b := a
fmt.Printf("a.v=%d, a.p=%d; b.v=%d, b.p=%d\n", a.v, *a.p, b.v, *b.p)
a.Set(1)
fmt.Printf("a.v=%d, a.p=%d; b.v=%d, b.p=%d\n", a.v, *a.p, b.v, *b.p)
الإخراج:a.v=0, a.p=0; ب.ف=0، ب.ب=0
a.v=1, a.p=1; b.v=0, b.p=1a.v=0, a.p=0; b.v=0, b.p=0 a.v=1, a.p=1; b.v=0, b.p=1في هذا المثال، تصبح قيمة b غير صالحة بعد استدعاء a.Set(1)، لأن b.v لا يساوي *b.p. وذلك لأن المؤشر p في كل من a وb يشير إلى نفس القيمة الأساسية.
لتجنب مثل هذه المشكلات، يوصى بالعمل مع قيم المؤشر عند استخدام الطرق مع مستقبلات المؤشر. وبدلاً من ذلك، إذا كان النوع يمكن أن يحتوي على مستقبلات قيمة فقط، فمن الآمن نسخ مثيلات من هذا النوع بغض النظر عن استدعاءات الطريقة.
تنصل: جميع الموارد المقدمة هي جزئيًا من الإنترنت. إذا كان هناك أي انتهاك لحقوق الطبع والنشر الخاصة بك أو الحقوق والمصالح الأخرى، فيرجى توضيح الأسباب التفصيلية وتقديم دليل على حقوق الطبع والنشر أو الحقوق والمصالح ثم إرسالها إلى البريد الإلكتروني: [email protected]. سوف نتعامل مع الأمر لك في أقرب وقت ممكن.
Copyright© 2022 湘ICP备2022001581号-3