DEV Community

Cover image for Uses and difference b/w switch and match
Swastik Baranwal
Swastik Baranwal

Posted on • Updated on

Uses and difference b/w switch and match

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

What was the need for 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 needs 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;
    }
}
Enter fullscreen mode Exit fullscreen mode

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 limitations:

  • 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 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 (though 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 the values matches
        _ => println!("something else"),
    }
}
Enter fullscreen mode Exit fullscreen mode

Using ranges and combining multiple values 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");
}
Enter fullscreen mode Exit fullscreen mode

Exceptions

Some languages like Go, JS, TS etc have switch statements but support all primitive data types though they don't have support for ranges, using them as expressions and have default as the 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")
}
Enter fullscreen mode Exit fullscreen mode

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 a statement only.

Some languages might not even use switch (f.e. Kotlin with the when which has the 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 become much complex.

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

Some languages 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.

Top comments (0)