loading...
Cover image for Uses and difference b/w switch and match

Uses and difference b/w switch and match

delta456 profile image Swastik Baranwal Updated on ・4 min read

Everyone must be using selection statements for pattern matching or equality checking. Some language like Rust, F#, Kotlin, Scala, V and Python (future) use matchand while some use switch like C, C++, Go, C# etc.

What was the need of separate names for the same purpose? This article tries to clarify the difference and usage between these two.

switch statement

A switch statement allows a variable to be tested for equality against a list of values. Each value is called case but need to be terminated by break. switch can also have a default case for handling other cases which are not listed.

Here's a simple switch Statement Program in C++.

#include <iostream>

int main()
{
  int i = 0;
  switch (i)
    {
    case 0:
      std::cout << "i is zero";
      break;

    case 1:
      std::cout << "i is one";
      break;

    default:
      std::cout << "invalid";
      break;
    }
}

This program declares variable i as int and the switch statement checks the value of i. The first case will be evaluated as it satisfied the condition i == 0 so i is zero will be printed.

Though switch has certain limitation:

  • switch only works with integral values i.e. int, char and enum
  • switch can only be used for checking equality
  • switch cannot be used as an expression

match statement/expression

match can be used be both used as a statement and expression accordingly and are much like switch except it solves the above limitation stated plus saves additional keywords over switch like no default or case (thought Python has case and it's a statement). default is either replaced with else or _ (some may just use default).

match also supports range like 1..2 which means in a range of [1, 2) and 1..=3 or 1...3 which means [1, 3], 2 | 3 | 4 or 3, 4, 5 for matching if either of them is true plus matching them as a var/object.

The following examples of match are written in Rust.

Taken from Learn Rust by Examples

Simple example

fn main() {
    let x = 1;

    match x {
        1 => println!("one"),
        2 => println!("two"),
        3 => println!("three"),
        4 => println!("four"),
        5 => println!("five"),
       // else clause, executed when none of value matches
        _ => println!("something else"),
    }
}

Using ranges and combining multiple values and as an expression

fn main() {
    let x = 1;
    let message = match x {
        0 | 1 => "not many",  // check if matches either to 0 or 1
        2..=9 => "a few",     // check if its in a range of `[2, 9]`
        10..15 => "too many", // check if its in a range of `[10, 15)`
        // else clause, if neither of the cases matches then "lots of
        // many" will be assigned
        _ => "lots of many",
    };

    assert_eq!(message, "a few");
}

Exceptions

Some languages like Go, JS, TS etc have switch statements but supports all primitive data types though they don't have support for ranges, using them as expression and have default as keyword, pattern matching etc.

In Go, there's no need to put break on every case, it does it automatically plus you can use interface{} to detect the type of the variable.

An example of Go's switch

Taken from Go By Examples

Simple example

package main

import (
    "fmt"
    "time"
)

func main() {

    // Here's a basic `switch`.
    i := 2
    fmt.Print("Write ", i, " as ")
    switch i {
    case 1:
        fmt.Println("one")
    case 2:
        fmt.Println("two")
    case 3:
        fmt.Println("three")
    }

    // You can use commas to separate multiple expressions
    // in the same `case` statement. We use the optional
    // `default` case in this example as well.
    switch time.Now().Weekday() {
    case time.Saturday, time.Sunday:
        fmt.Println("It's the weekend")
    default:
        fmt.Println("It's a weekday")
    }

    // `switch` without an expression is an alternate way
    // to express if/else logic. Here we also show how the
    // `case` expressions can be non-constants.
    t := time.Now()
    switch {
    case t.Hour() < 12:
        fmt.Println("It's before noon")
    default:
        fmt.Println("It's after noon")
    }

    // A type `switch` compares types instead of values.  You
    // can use this to discover the type of an interface
    // value.  In this example, the variable `t` will have the
    // type corresponding to its clause.
    whatAmI := func(i interface{}) {
        switch t := i.(type) {
        case bool:
            fmt.Println("I'm a bool")
        case int:
            fmt.Println("I'm an int")
        default:
            fmt.Printf("Don't know type %T\n", t)
        }
    }
    whatAmI(true)
    whatAmI(1)
    whatAmI("hey")
}

Conclusions

match and switch are just convenient ways of writing long if-else statements for increasing readability and making code more robust etc.

Usually, match is used for pattern matching and also it can be a statement and as well as expression whereas switch is used for equality checking and is statement only.

Some languages might not even use switch (f.e. Kotlin with the when which has same semantics as match)

Dynamically and statically typed languages often do things differently on their specific use cases. Some may provide or disallow certain features so that the language doesn't becomes much complex.

Similarly, V only supports inclusive range of the last element i.e. start...end which is same as [start, end] to remove the complexity.

Some language may even keep switch for simplicity and easiness to use.

References

If there's anything wrong in this article then please reply in the comments.

Discussion

pic
Editor guide