تفاصيل ونصائح

يمكن تحويل قيم نوعين مسمّيين مختلفين من المؤشرات إلى نوع أحدهما الآخر بشكل غير مباشر إذا كان النوعان الأساسيان للنوعين يتشاركان النوع الكامن نفسه

عموماً، لا يجوز تحويل قيم نوعين من المؤشرات إلى نوع أحدهما الآخر إذا كان النوعان الكامنان لنوعي المؤشر مختلفين. مثلاً، التحويلات الأربعة في الشيفرة التالية كلها غير قانونية.

package main

type MyInt int
type IntPtr *int     // النوع الكامن هو *int
type MyIntPtr *MyInt // النوع الكامن هو *MyInt

func main() {
	var x IntPtr
	var y MyIntPtr
	x = IntPtr(y)       // خطأ
	y = MyIntPtr(x)     // خطأ
	var _ = (*int)(y)   // خطأ
	var _ = (*MyInt)(x) // خطأ
}

رغم أن التحويلات الأربعة أعلاه لا يمكن إنجازها مباشرةً، فإنه يمكن إنجازها بشكل غير مباشر. وهذا بفضل كون التحويلات التالية قانونية.

package main

type MyInt int

func main() {
	var x *int
	var y *MyInt
	x = (*int)(y)   // حسن
	y = (*MyInt)(x) // حسن
}

السبب في أن التحويلين أعلاه قانونيان هو أنه يمكن تحويل قيم نوعين غير مسمّيين من المؤشرات إلى نوع أحدهما الآخر إذا كان النوعان الأساسيان للنوعين يتشاركان النوع الكامن نفسه. في المثال أعلاه، النوعان الأساسيان لنوعَي x وy هما int وMyInt، وهما يتشاركان النوع الكامن نفسه int، لذا يمكن تحويل x وy إلى نوع أحدهما الآخر.

واستفادةً من الحقيقة المذكورة للتو، يمكن أيضاً تحويل قيم IntPtr وMyIntPtr إلى نوع أحدهما الآخر، مع أن هذه التحويلات يجب أن تكون غير مباشرة، كما هو موضح في الشيفرة التالية.

package main

type MyInt int
type IntPtr *int
type MyIntPtr *MyInt

func main() {
	var x IntPtr
	var y MyIntPtr
	x = IntPtr((*int)((*MyInt)(y)))     // حسن
	y = MyIntPtr(((*MyInt))((*int)(x))) // حسن
	var _ = (*int)((*MyInt)(y))         // حسن
	var _ = (*MyInt)((*int)(x))         // حسن
}