يتطلب Go تحويلًا صريحًا بين الأنواع المختلفة.
يتم التحويل بين الأنواع (المعروف أيضًا بـ type casting) عبر دالة تحمل اسم النوع المراد التحويل إليه.
على سبيل المثال، لتحويل int إلى float64 عليك القيام بما يلي:
var x int = 42 // x has type int
f := float64(x) // f has type float64 (ie. 42.0)
توجد حزمة strconv للتحويل بين الأنواع الأولية (مثل int) وstring.
import "strconv"
var intString string = "42"
var i, err = strconv.Atoi(intString)
var number int = 12
var s string = strconv.Itoa(number)
قد تُدخل الواجهات في Go غموضًا بشأن النوع الكامن.
يتيح لنا تأكيد النوع استخراج القيمة الملموسة الكامنة لقيمة الواجهة باستخدام هذه الصيغة: interfaceVariable.(concreteType).
على سبيل المثال:
var input any = 12
number := input.(int)
ملاحظة: سيؤدي هذا إلى panic إذا لم يحتوِ متغير الواجهة على قيمة من النوع الملموس.
يمكننا اختبار ما إذا كانت قيمة الواجهة تحمل نوعًا ملموسًا محددًا بالاستفادة من قيمتي الإرجاع لتأكيد النوع: القيمة الكامنة وقيمة منطقية تخبرنا ما إذا نجح التأكيد. على سبيل المثال:
str, ok := input.(string) // no panic if input is not a string
إذا كانت input تحمل string، فستكون str هي القيمة الكامنة وستكون ok هي صحيح.
وإذا لم تكن input تحمل string، فستكون str هي القيمة الصفرية للنوع string (أي ""، السلسلة النصية الفارغة) وستكون ok هي خطأ.
ولا يحدث panic في أي حالة.
يمكن لـتبديل النوع إجراء عدة تأكيدات نوع بالتتابع.
وهو يستخدم الصيغة نفسها التي يستخدمها تأكيد النوع (interfaceVariable.(concreteType))، لكن يُستبدل concreteType بالكلمة المفتاحية type.
إليك مثالًا:
var i any = 12 // try: 12.3, true, int64(12), []int{}, map[string]int{}
switch v := i.(type) {
case int:
fmt.Printf("the integer %d\n", v)
case string:
fmt.Printf("the string %s\n", v)
default:
fmt.Printf("type, %T, not handled explicitly: %#v\n", v, v)
}
تعمل جين في غرفة الفرز في مصنع كبير. تحتاج غرفة الفرز إلى معالجة كل ما يصل إليها بتصنيفه ووضع ملصق عليه. جين مسؤولة عن الأشياء التي صُنّفت مسبقًا كأعداد، وتحتاج إلى برنامج يساعدها في الفرز.
معظم القيم الأولية ينبغي أن تحصل على ملصقات مباشرة.
بالنسبة إلى الأعداد، تريد سلاسل نصية تقول "This is the number 2.0" (إذا كان العدد 2).
تريد جين المخرَج نفسه للأعداد الصحيحة والأعداد العشرية.
هناك بعض الواجهات Box التي يجب فكّها للحصول على محتوياتها.
بالنسبة إلى NumberBox، تريد سلاسل نصية تقول "This is a box containing the number 3.0" (إذا أرجعت الطريقة Number() القيمة 3).
وبالنسبة إلى FancyNumberBox، تريد سلاسل نصية تقول "This is a fancy box containing the number 4.0"، ولكن فقط إذا كان النوع FancyNumber.
أي شيء غير متوقع ينبغي أن يقول "Return to sender" حتى تتمكن جين من إعادته إلى مصدره.
تريد جين أن تُرجع الأعداد سلاسل نصية مثل "This is the number 2.0" (مع رقم واحد بعد الفاصلة العشرية):
fmt.Println(DescribeNumber(-12.345))
// Output: This is the number -12.3
تريد جين أن تُرجع صناديق الأعداد سلاسل نصية مثل "This is a box containing the number 2.0" (مرة أخرى، مع رقم واحد بعد الفاصلة العشرية):
fmt.Println(DescribeNumberBox(numberBoxContaining{12}))
// Output: This is a box containing the number 12.0
تحتاج جين إلى دالة مساعدة لاستخراج العدد من FancyNumberBox.
إذا كان FancyNumberBox من نوع FancyNumber، فاستخرج قيمته وحوّلها من string إلى int.
أي نوع آخر من FancyNumberBox ينبغي أن يُرجع 0.
fmt.Println(ExtractFancyNumber(FancyNumber{"10"}))
// Output: 10
fmt.Println(ExtractFancyNumber(AnotherFancyNumber{"4"}))
// Output: 0
إذا كان FancyNumberBox من نوع FancyNumber، تريد جين سلاسل نصية تقول "This is a fancy box containing the number 4.0".
أي نوع آخر من FancyNumberBox ينبغي أن يقول "This is a fancy box containing the number 0.0".
fmt.Println(DescribeFancyNumberBox(FancyNumber{"10"}))
// Output: This is a fancy box containing the number 10.0
fmt.Println(DescribeFancyNumberBox(AnotherFancyNumber{"4"}))
// Output: This is a fancy box containing the number 0.0
ملاحظة: ينبغي أن نستخدم الدالة ExtractFancyNumber!
DescribeAnything التي تستخدمها جميعًاهذه هي الدالة الرئيسية التي تحتاجها جين، وهي تأخذ أي مدخل.
ينبغي أن تُفوّض DescribeAnything إلى الدوال الأخرى بناءً على نوع القيمة المُمرَّرة.
وبشكل أكثر تحديدًا:
int وfloat64 إلى DescribeNumber
NumberBox إلى DescribeNumberBox
FancyNumberBox إلى DescribeFancyNumberBox
"Return to sender"
fmt.Println(DescribeAnything(numberBoxContaining{12.345}))
// Output: This is a box containing the number 12.3
fmt.Println(DescribeAnything("some string"))
// Output: Return to sender
سجّل في Exercism لتتعلّم وتتقن Go عبر 34 مفهومًا166 تمرينًا، وإرشاد بشري حقيقي، وكل ذلك مجانًا.