Start learning free

LESSON 80 OF 338 · CONDITIONAL STATEMENTS

Combining Logical Operators in Go: &&, || and Parentheses

Lesson Read the full explanation

Logical operators can be combined to express more complex rules.

Use parentheses to make the grouping clear:

specialStudent := false
age := 23

if specialStudent || (age >= 18 && age <= 30) {
    fmt.Println("Let him in!")
} else {
    fmt.Println("Not allowed")
}

This allows entry if the student is special, or if the age is between 18 and 30 inclusive.

Assignment
Combine || and && to check the entry rule.


STEP 1 OF 2
    Ctrl + Enter to check

    GO · CONDITIONAL STATEMENTS

    Combining Logical Operators in Go, explained

    Why combine operators

    Real rules are rarely a single comparison. "Special students may enter, and so may anyone aged 18 to 30" has an or in the middle and an and inside one side. Go lets you build such rules from && (and), || (or) and ! (not), as long as each piece is a boolean expression.

    A short refresher: a && b is true only when both sides are true, and a || b is true when at least one side is.

    Precedence: who goes first

    When one condition mixes && and ||, Go groups the && parts first, in the same way that multiplication happens before addition. Both of the following lines are evaluated like this:

    t, f := true, false
    fmt.Println(t || f && f)   // true: same as t || (f && f)
    fmt.Println((t || f) && f) // false: the parentheses change the grouping
    

    The first line prints true and the second prints false, with identical operands. Parentheses are free, so use them whenever a reader would have to stop and think about the order, even where the order is already right.

    The lesson's exercise

    The code declares two variables:

    var specialStudent bool = false
    var age int = 23
    

    The entry rule is: let the student in if specialStudent is true, or if age is between 18 and 30, both ends included.

    Step 1: the if statement

    "Between 18 and 30" is two comparisons that must both hold: age >= 18 && age <= 30. Go has no chained comparison like 18 <= age <= 30, so the age appears twice. Because both ends are included, the operators are >= and <=. Wrap that pair in parentheses, then join it to specialStudent with ||.

    Step 2: the else branch

    Add } else { and print "Not allowed". It runs for anyone who fails both checks: not special, and younger than 18 or older than 30.

    The solution in Go

    var specialStudent bool = false
    var age int = 23
    
    if (specialStudent || (age >= 18 && age <= 30)) {
        fmt.Println("Let him in!")
    } else {
        fmt.Println("Not allowed")
    }
    

    Reading it from the inside out: age >= 18 && age <= 30 is true for 23, so the || is true even though specialStudent is false, and the program prints Let him in!.

    The outermost parentheses are allowed but not needed, because Go does not require parentheses around an if condition. Most Go code, and the gofmt tool, leaves them out; the inner parentheses are the useful ones.

    Trying different ages

    With specialStudent set to false, the rule behaves like this:

    ageresult
    17Not allowed
    18Let him in!
    30Let him in!
    31Not allowed

    With specialStudent set to true, every age is let in, since the left side of || is already true and Go does not even evaluate the age comparisons.

    Breaking a rule into pieces

    When a rule gets long, name its parts. Boolean variables cost nothing and make the final condition read like the rule itself:

    inRange := age >= 18 && age <= 30
    if specialStudent || inRange {
        fmt.Println("Let him in!")
    }
    

    This behaves exactly like the version with the age check written inline. Use whichever form reads better; for a rule with two or three parts, the inline form is fine.

    Go details worth knowing

    • Short-circuiting. && stops at the first false operand and || stops at the first true one. Later operands are not evaluated, which matters for operands with side effects or ones that would fail, such as an index that might be out of range.
    • Booleans only. Every operand must be a bool. Comparing with == true is legal but redundant; write specialStudent alone.
    • The else layout. Go requires else on the same line as the closing brace. On its own line, the program does not compile.
    • Declared variables must be used. If you remove the use of age, the compiler reports declared and not used.

    Common mistakes

    • Using || inside the age range. age >= 18 || age <= 30 is true for every integer. A range needs both bounds to hold, which is &&.
    • Exclusive bounds. Writing age > 18 && age < 30 rejects 18 and 30, which the rule allows.
    • Dropping the inner parentheses. specialStudent || age >= 18 && age <= 30 happens to mean the same thing, but (specialStudent || age >= 18) && age <= 30 does not: it would reject a special student older than 30.
    • Chained comparisons. 18 <= age <= 30 is a compile error in Go.

    Key takeaways

    • && binds tighter than ||; parentheses override the order and make it visible.
    • A range check is two comparisons joined with &&.
    • Evaluation stops early once the result is known.
    • The else branch handles everyone who fails every check above it.
    Keep going with GoAbout 340 step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free