يمكن لدوال Go وطرقها إرجاع قيم متعددة:
func GetCard() (Card, error) { ... }
يجب إسناد كل قيمة مُرجَعة بالترتيب، مع فصلها بفواصل:
card, err := GetCard()
كل موضع في الإسناد يُعرِّف متغيرًا.
ولا يسمح Go بتعريف متغير دون استخدامه.
استخدم المعرّف الفارغ _ بدلًا من اسم المتغير لتتخطى تلك القيمة المُرجَعة.
card, _ := GetCard() // error intentionally ignored
_, err := GetCard() // card ignored, only checking for error
error واجهة مدمجة.
خطأ بقيمة nil يعني أنه لم يحدث أي خطأ، وأي قيمة غير nil تعني أن هناك خطأ ما.
بحسب العُرف، ينبغي للدوال التي قد تفشل أن تُرجع error كقيمة أخيرة لها.
وعلى المستدعي أن يتحقق منه قبل استخدام أي قيم مُرجَعة أخرى:
card, err := GetCard()
if err != nil {
// unsafe to use card here
return err
}
// safe to use card here
ok
يظهر نمط الإسناد ذو القيمتين أيضًا خارج معالجة error.
فعمليات البحث في الخرائط، وتأكيدات الأنواع، والاستقبال من القنوات، كلها تستخدم قيمة منطقية ثانية، يُطلق عليها ok بحسب العُرف، للدلالة على النجاح أو على وجود بيانات:
m := map[string]int{"a": 1}
v, ok := m["a"] // ok is true
v, ok = m["z"] // ok is false
var i interface{} = "hello"
v, ok := i.(string) // ok is true
v, ok = i.(int) // ok is false
v, ok := <-ch // ok is false if ch is closed and empty
يمكن أيضًا إعطاء أسماء لقيم الإرجاع في توقيع الدالة. وعندها يمكن الوصول إلى هذه المتغيرات داخل جسم الدالة.
func divide(a, b int) (quotient, remainder int) {
quotient = a / b
remainder = a % b
return quotient, remainder
}
توثّق قيم الإرجاع المُسمّاة معنى كل موضع إرجاع. ويمكن استخدامها أيضًا مع إرجاع عارٍ، أي إرجاع يُكتب دون قيم. فالإرجاع العاري يُرجع ضمنيًا القيم الحالية للمتغيرات المُسمّاة:
func split(sum int) (x, y int) {
x = sum * 4 / 9
y = sum - x
return
}
في الدوال الطويلة، غالبًا ما يضرّ الإرجاع العاري بقابلية القراءة، لأنه يجعل ما يتم إرجاعه غير واضح. فضّل قيم الإرجاع الصريحة، إلا إذا كانت الدالة قصيرة بما يكفي ليبقى توقيعها في مرمى النظر دائمًا.
لمعرفة المزيد، اطّلع على Go by Example: Multiple Return Values، وEffective Go: Multiple Returns، أو Tour of Go.