Switch
The switch statement is shorthand for writing a series of if statements that check against the same value. Note that the value is only evaluated once. Like if statements, switches can have an else block to handle no matches. Comparison is done with the == operator. In switch statement, you can also use assignment expression to store temporary variable value.
switch name := "Dan" when "Robert" print "You are Robert" when "Dan", "Daniel" print "Your name, it's Dan" else print "I don't know about you with name #{name}"switch name := "Dan" when "Robert" print "You are Robert" when "Dan", "Daniel" print "Your name, it's Dan" else print "I don't know about you with name #{name}"A switch when clause can match against multiple values by listing them out comma separated.
Switches can be used as expressions as well, here we can assign the result of the switch to a variable:
b = 1next_number = switch b when 1 2 when 2 3 else error "can't count that high!"b = 1next_number = switch b when 1 2 when 2 3 else error "can't count that high!"We can use the then keyword to write a switch’s when block on a single line. No extra keyword is needed to write the else block on a single line.
msg = switch math.random(1, 5) when 1 then "you are lucky" when 2 then "you are almost lucky" else "not so lucky"msg = switch math.random(1, 5) when 1 then "you are lucky" when 2 then "you are almost lucky" else "not so lucky"If you want to write code with one less indent when writing a switch statement, you can put the first when clause on the statement start line, and then all other clauses can be written with one less indent.
switch math.random(1, 5) when 1 print "you are lucky" -- two indents else print "not so lucky"
switch math.random(1, 5) when 1 print "you are lucky" -- one indentelse print "not so lucky"switch math.random(1, 5) when 1 print "you are lucky" -- two indents else print "not so lucky"
switch math.random(1, 5) when 1 print "you are lucky" -- one indentelse print "not so lucky"It is worth noting the order of the case comparison expression. The case’s expression is on the left hand side. This can be useful if the case’s expression wants to overwrite how the comparison is done by defining an eq metamethod.
Table Matching
Section titled “Table Matching”You can do table matching in a switch when clause, if the table can be destructured by a specific structure and get non-nil values.
items = * x: 100 y: 200 * width: 300 height: 400
for item in *items switch item when :x, :y print "Vec2 #{x}, #{y}" when :width, :height print "size #{width}, #{height}"items = * x: 100 y: 200 * width: 300 height: 400
for item in *items switch item when :x, :y print "Vec2 #{x}, #{y}" when :width, :height print "size #{width}, #{height}"You can use default values to optionally destructure the table for some fields.
item = {}
{pos: {:x = 50, :y = 200}} = item -- get error: attempt to index a nil value (field 'pos')
switch item when {pos: {:x = 50, :y = 200}} print "Vec2 #{x}, #{y}" -- table destructuring will still passitem = {}
{pos: {:x = 50, :y = 200}} = item -- get error: attempt to index a nil value (field 'pos')
switch item when {pos: {:x = 50, :y = 200}} print "Vec2 #{x}, #{y}" -- table destructuring will still passYou can also match against array elements, table fields, and even nested structures with array or table literals.
Match against array elements.
switch tb when [1, 2, 3] print "1, 2, 3" when [1, b, 3] print "1, #{b}, 3" when [1, 2, b = 3] -- b has a default value print "1, 2, #{b}"switch tb when [1, 2, 3] print "1, 2, 3" when [1, b, 3] print "1, #{b}, 3" when [1, 2, b = 3] -- b has a default value print "1, 2, #{b}"Match against table fields with destructuring.
switch tb when success: true, :result print "success", result when success: false print "failed", result else print "invalid"switch tb when success: true, :result print "success", result when success: false print "failed", result else print "invalid"Match against nested table structures.
switch tb when data: {type: "success", :content} print "success", content when data: {type: "error", :content} print "failed", content else print "invalid"switch tb when data: {type: "success", :content} print "success", content when data: {type: "error", :content} print "failed", content else print "invalid"Match against array of tables.
switch tb when [ {a: 1, b: 2} {a: 3, b: 4} {a: 5, b: 6} fourth ] print "matched", fourthswitch tb when [ {a: 1, b: 2} {a: 3, b: 4} {a: 5, b: 6} fourth ] print "matched", fourthMatch against a list and capture a range of elements.
segments = ["admin", "users", "logs", "view"]switch segments when [...groups, resource, action] print "Group:", groups -- prints: {"admin", "users"} print "Resource:", resource -- prints: "logs" print "Action:", action -- prints: "view"segments = ["admin", "users", "logs", "view"]switch segments when [...groups, resource, action] print "Group:", groups -- prints: {"admin", "users"} print "Resource:", resource -- prints: "logs" print "Action:", action -- prints: "view"