Master Go's conditional statements for intelligent decision-making in your programs. This comprehensive guide covers if-else statements, switch statements, and advanced conditional patterns, building upon our understanding of loops and data types.
Key Points
Clean and readable conditional syntax
Powerful switch statements with multiple patterns
Short variable declarations in conditions
Type switches for interface handling
Fallthrough control in switch cases
Understanding Conditional Logic
Conditional statements are the decision-making backbone of any program. Go provides elegant and powerful constructs for handling different execution paths.
Conditional Constructs in Go
graph TD
A[Go Conditionals] --> B[If-Else]
A --> C[Switch]
B --> B1[Basic If]
B --> B2[If-Else]
B --> B3[If-Else If]
B --> B4[Short Declaration]
C --> C1[Expression Switch]
C --> C2[Type Switch]
C --> C3[No Expression]
C --> C4[Fallthrough]
style A fill:#999,stroke:#333,stroke-width:2px,color:#000
If-Else Statements: Basic Decision Making
The if-else family provides straightforward conditional execution based on boolean expressions.
packagemainimport"fmt"funcmain(){age:=25income:=50000creditScore:=720ifage>=18&&income>=30000&&creditScore>=650{fmt.Println("Loan approved!")}elseifage<18{fmt.Println("Must be 18 or older")}elseifincome<30000{fmt.Println("Insufficient income")}else{fmt.Println("Credit score too low")}// Output: Loan approved!}
Short Variable Declaration in If
Go allows you to declare and initialize variables within if statements, creating a limited scope.
packagemainimport"fmt"funcmain(){// Variable declared in if statementifx:=10;x>5{fmt.Printf("x is %d and greater than 5\n",x)}// x is not accessible here// Output: x is 10 and greater than 5}
Scope Limitation
Variables declared in if statements are only accessible within the if-else block.
packagemainimport"fmt"funcgetTemperature()int{return25}funcmain(){// Call function and use result in conditioniftemp:=getTemperature();temp>20{fmt.Printf("Temperature is %d°C - Nice weather!\n",temp)}else{fmt.Printf("Temperature is %d°C - A bit cold\n",temp)}// Output: Temperature is 25°C - Nice weather!}
Switch Statements: Multi-Way Branching
Switch statements provide an elegant way to handle multiple conditions and are more readable than long if-else chains.
packagemainimport"fmt"funcmain(){day:="Monday"switchday{case"Monday":fmt.Println("Start of the work week")case"Friday":fmt.Println("TGIF!")case"Saturday","Sunday":fmt.Println("Weekend!")default:fmt.Println("Regular weekday")}// Output: Start of the work week}
packagemainimport"fmt"funcmain(){char:='a'switchchar{case'a','e','i','o','u':fmt.Printf("'%c' is a vowel\n",char)case'y':fmt.Printf("'%c' is sometimes a vowel\n",char)default:fmt.Printf("'%c' is a consonant\n",char)}// Output: 'a' is a vowel}
packagemainimport"fmt"funcmain(){number:=2switchnumber{case1:fmt.Println("One")fallthroughcase2:fmt.Println("Two or after One")fallthroughcase3:fmt.Println("Three or after Two")default:fmt.Println("Other number")}// Output:// Two or after One// Three or after Two}
packagemainimport"fmt"funcclassify(nint)string{ifn%2==0{return"even"}return"odd"}funcmain(){number:=7switchclassify(number){case"even":fmt.Printf("%d is an even number\n",number)case"odd":fmt.Printf("%d is an odd number\n",number)default:fmt.Printf("Unknown classification for %d\n",number)}// Output: 7 is an odd number}
Type Switch
Type switches are a powerful feature for working with interfaces and determining the actual type of a value.
packagemainimport"fmt"funcmain(){age:=25hasJob:=truecreditScore:=750// AND operatorifage>=18&&hasJob&&creditScore>=700{fmt.Println("Eligible for premium loan")}// OR operatorifage<18||creditScore<600{fmt.Println("Not eligible for loan")}else{fmt.Println("Basic loan eligibility met")}// NOT operatorif!(age<18){fmt.Println("Adult")}// Output:// Eligible for premium loan// Basic loan eligibility met// Adult}
packagemainimport"fmt"funcexpensiveCheck()bool{fmt.Println("Expensive check called")returntrue}funcmain(){condition:=false// expensiveCheck() won't be called due to short-circuitifcondition&&expensiveCheck(){fmt.Println("Both conditions true")}// expensiveCheck() will be calledif!condition||expensiveCheck(){fmt.Println("At least one condition true")}// Output:// Expensive check called// At least one condition true}
packagemainimport"fmt"funcmain(){weather:="sunny"temperature:=25ifweather=="sunny"{iftemperature>20{fmt.Println("Perfect day for outdoor activities!")}else{fmt.Println("Sunny but a bit cold")}}elseifweather=="rainy"{iftemperature>15{fmt.Println("Warm rain - good for plants")}else{fmt.Println("Cold and rainy - stay inside")}}else{fmt.Println("Weather conditions unclear")}// Output: Perfect day for outdoor activities!}
packagemainimport"fmt"funcprocessUser(namestring,ageint,emailstring){// Guard clauses for early returnsifname==""{fmt.Println("Error: Name cannot be empty")return}ifage<0||age>150{fmt.Println("Error: Invalid age")return}ifemail==""{fmt.Println("Error: Email cannot be empty")return}// Main processing logicfmt.Printf("Processing user: %s, age %d, email %s\n",name,age,email)}funcmain(){processUser("Alice",25,"alice@example.com")processUser("",30,"bob@example.com")processUser("Charlie",-5,"charlie@example.com")}
// Good: Use switch for multiple discrete valuesswitchstatus{case"pending","processing":handleInProgress()case"completed":handleCompleted()case"failed":handleFailed()}// Avoid: Long if-else chainsifstatus=="pending"||status=="processing"{handleInProgress()}elseifstatus=="completed"{handleCompleted()}elseifstatus=="failed"{handleFailed()}
funcvalidate(inputstring)error{ifinput==""{returnerrors.New("input cannot be empty")}iflen(input)>100{returnerrors.New("input too long")}// Continue with main logicreturnnil}
packagemainimport"fmt"funcprocessWithSwitch(valueint)string{// Generally faster for many discrete valuesswitchvalue{case1,2,3:return"low"case4,5,6:return"medium"case7,8,9:return"high"default:return"unknown"}}funcprocessWithIfElse(valueint)string{// Better for range conditionsifvalue>=1&&value<=3{return"low"}elseifvalue>=4&&value<=6{return"medium"}elseifvalue>=7&&value<=9{return"high"}else{return"unknown"}}funcmain(){fmt.Println(processWithSwitch(5))fmt.Println(processWithIfElse(5))}
packagemainimport"fmt"funccheckConditions(valueint)string{// Order conditions by likelihood (most common first)ifvalue>=0&&value<=100{// Most common casereturn"normal range"}elseifvalue<0{// Less commonreturn"negative"}else{// Least commonreturn"above range"}}funcmain(){fmt.Println(checkConditions(50))}
Quick Reference
Key Takeaways
If-Else: Use for boolean conditions and ranges
Switch: Prefer for discrete values and type checking
Short Declaration: Leverage for scoped variables in conditions
Type Switch: Essential for interface type determination
Guard Clauses: Use for early returns and validation
Performance: Consider condition ordering and switch vs if-else trade-offs
Remember
"Choose the right conditional construct for the job. Switch for discrete values, if-else for ranges and complex boolean logic, and type switches for interface handling."