التحكم الشرطي في Go
في Go، هناك ثلاثة أنواع من عبارات التحكم الشرطي: if، switch، select. select مختلف نسبياً عن الأولين، لن يتم شرحه في هذا القسم، وسيتم تقديمه في قسم التزامن.
if else
if else لديه على الأكثر فرعين للحكم، صيغة العبارة كالتالي:
if expression {
}أو
if expression {
}else {
}يجب أن يكون expression تعبيراً منطقياً، أي أن النتيجة إما صحيحة أو خاطئة، يجب أن تكون قيمة منطقية، مثال:
func main() {
a, b := 1, 2
if a > b {
b++
} else {
a++
}
}يمكن أيضاً كتابة تعبير أكثر تعقيداً، وعند الضرورة لتحسين القراءة، يجب استخدام الأقواس لإظهار بشكل صريح ما يجب أن يُحسب أولاً.
func main() {
a, b := 1, 2
if a<<1%100+3 > b*100/20+6 { // (a<<1%100)+3 > (b*100/20)+6
b++
} else {
a++
}
}كما يمكن لعبارة if أن تحتوي على بعض العبارات البسيطة، مثلاً:
func main() {
if x := 1 + 1; x > 2 {
fmt.Println(x)
}
}else if
عبارة else if يمكنها إنشاء المزيد من فروع الحكم على أساس if else، صيغة العبارة كالتالي:
if expression1 {
}else if expression2 {
}else if expression3 {
}else {
}أثناء التنفيذ، يتم تقييم كل تعبير من اليسار إلى اليمين، ويتم تقييم عبارة if بأكملها من الأعلى إلى الأسفل. مثال لتقييم الدرجات:
func main() {
score := 90
var ans string
if score == 100 {
ans = "S"
} else if score >= 90 && score < 100 {
ans = "A"
} else if score >= 80 && score < 90 {
ans = "B"
} else if score >= 70 && score < 80 {
ans = "C"
} else if score >= 60 && score < 70 {
ans = "E"
} else if score >= 0 && score < 60 {
ans = "F"
} else {
ans = "nil"
}
fmt.Println(ans)
}الطريقة الثانية تستخدم فرضية أن عبارة if تُقيَّم من الأعلى إلى الأسفل، لذا الكود أكثر إيجازاً.
func main() {
score := 90
var ans string
if score >= 0 && score < 60 {
ans = "F"
} else if score < 70 {
ans = "D"
} else if score < 80 {
ans = "C"
} else if score < 90 {
ans = "B"
} else if score < 100 {
ans = "A"
} else if score == 100 {
ans = "S"
}else {
ans = "nil"
}
fmt.Println(ans)
}switch
عبارة switch هي أيضاً عبارة حكم متعددة الفروع، صيغة العبارة كالتالي:
switch expr {
case case1:
statement1
case case2:
statement2
default:
default statement
}مثال بسيط:
func main() {
str := "a"
switch str {
case "a":
str += "a"
str += "c"
case "b":
str += "bb"
str += "aaaa"
default: // عندما لا يتطابق أي case، يتم تنفيذ فرع default
str += "CCCC"
}
fmt.Println(str)
}يمكن أيضاً كتابة بعض العبارات البسيطة قبل التعبير، مثلاً تعريف متغير جديد:
func main() {
switch num := f(); { // مكافئة لـ switch num := f(); true {
case num >= 0 && num <= 1:
num++
case num > 1:
num--
fallthrough
case num < 0:
num += num
}
}
func f() int {
return 1
}يمكن أيضاً لعبارة switch أن تكون بدون تعبير في المدخل:
func main() {
num := 2
switch { // مكافئة لـ switch true {
case num >= 0 && num <= 1:
num++
case num > 1:
num--
case num < 0:
num *= num
}
fmt.Println(num)
}من خلال الكلمة المفتاحية fallthrough يمكن الاستمرار في تنفيذ الفرع التالي المجاور:
func main() {
num := 2
switch {
case num >= 0 && num <= 1:
num++
case num > 1:
num--
fallthrough // بعد تنفيذ هذا الفرع، سيستمر تنفيذ الفرع التالي
case num < 0:
num += num
}
fmt.Println(num)
}label
عبارة التسمية، تضع علامة على كتلة كود، يمكن أن تكون هدفاً لـ goto، break، continue. مثال:
func main() {
A:
a := 1
B:
b := 2
}استخدام التسمية وحدها لا معنى له، يجب استخدامها مع كلمات مفتاحية أخرى.
goto
goto ينقل التحكم إلى عبارة ذات تسمية مقابلة في نفس الدالة، مثال:
func main() {
a := 1
if a == 1 {
goto A
} else {
fmt.Println("b")
}
A:
fmt.Println("a")
}في التطبيقات العملية، goto يُستخدم نادراً، القفز من مكان لآخر يقلل من قراءة الكود، واستهلاك الأداء هو أيضاً مشكلة.
