Using a given value to direct the flow of program execution.
Python |
Qt/Cpp |
- from dataclasses import dataclass
- @dataclass
- class C:
- m_c: int
- isLetter : bool = False
- isNonCharacter : bool = False
- isNull : bool = False
- isNumber : bool = False
- isPrintable : bool = True
- isSpace : bool = False
- isUpper : bool = False
- c = C(88)
- match c:
- case C(0):
- c.isNull = True
- case C( m_c = x ) if x in range(1, 32) or x == 127:
- c.isNonCharacter = True
- c.isPrintable = False
- case C(" "):
- c.isSpace = True
- case C(x) if x in range( ord("A"), ord("Z") + 1 ):
- c.isUpper = True
- c.isLetter = True
- case C(x) if x in range( ord("a"), ord("z") + 1 ):
- c.isUpper = False
- c.isLetter = True
- case C(x) if x in range( ord("0"), ord("9") + 1 ):
- c.isNumber = True
- case _:
- pass
|
- qint8 c(88);
- bool isLetter (false);
- bool isNonCharacter(false);
- bool isNull (false);
- bool isNumber (false);
- bool isPrintable (true );
- bool isSpace (false);
- bool isUpper (false);
- switch (c) {
- default: break;
- case 0 :
- isNull = true;
- [[fallthrough]];
- case 1 ... 31:
- case 127 : // Delete
- isNonCharacter = true;
- isPrintable = false;
- break;
- case ' ':
- isSpace = true;
- break;
- case 'A' ... 'Z':
- isUpper = true;
- [[fallthrough]];
- case 'a' ... 'z':
- isLetter = true;
- break;
- case '0' ... '9':
- isNumber = true;
- break;
- }
|
Read as:
|
- 'match 'c [ a character dataclass ] where if:
- under case [ dataclass ] C(0)
- isNull equals true
-
- under case [ dataclass ] c is an instance of [ dataclass ] C which has an attribute m_c
- it will evaluate as true when we assign m_c to x and if x is in the range of 1 to 32 or is equal to 127,
- isNonCharacter equals true
- isPrintable equals false
-
- Under case [ dataclass ] C( space )
- isSpace equals true
-
- under case [ dataclass ] C( x [ which is a copy of the first attribute of C, m_c ] ) if x is in the range of A to Z,'
- isUpper equals true
- isLetter equals true
-
- under case [ dataclass ] C( x [ which is a copy of the first attribute of C, m_c ] ) if x is in the range of a to z,'
- isUpper equals false
- isLetter equals true
-
- under case [ dataclass ] C( x [ which is a copy of the first attribute of C, m_c ] ) if x is in the range of 0 to 9,'
- isNumber equals true
- under case underscore [ Which is a wildcard pattern, taking any argument ]
- pass [ and do nothing ]
|
- 'switch' c [ 'c' implying character value ]
- by default, 'break' [ out of the 'switch' ].
- Under case 0:
- isNull equals true.
- Fallthrough [ to the next case's code ]
- Under case from 1 to 31:
- Under case 127:
- isNonCharacter equals true.
- isPrintable equals false
- 'break' [ out of the 'switch' ]
- under case space character
- isSpace equals true.
- 'break' [ out of the 'switch' ]
- Under case from A to Z:
- isUpper equals true.
- Fallthrough [ to the next case's code ]
- Under case from a to z:
- isLetter equals true.
- 'break' [ out of the 'switch' ]
- Under case from 0 to 9:
- isNumber equals true.
- 'break' [ out of the 'switch' ]
|
Benefits:
|
- Cases support conditional triggers.
|
- A 'switch' here is transformed into a jump or lookup table for potential massive performance gains.
- In order to achieve this, the compiler guarantees that all case values are unique numeric values.
- Because of the unique value nature, the order of the case statements is more or less immaterial unless one plans to make fallthrough code
- Code can fallthrough allowing for subtle optimization.
- Offers excellent readability if working in tandem with enumerators
|
Drawbacks:
|
- Extremely unintuitive syntax.
- No fallthrough.
- Performatively poor, due to the fact that no jump is executed.
- Cases are not guaranteed unique.
- Two cases may evaluate as true, however only the first will execute
|
- Value has to be translateable to an interger form
- [[fallthrough]] is optional, and absent this, it may be easy to not realize that no 'break'is occurring.
- '0' has a different value than 0. Although this remains true in python as well in similar contexts.
|