Case(在其他语言中常称为 switch)是一种类似 if-else 的控制表达式。 Case 能串联多个 if-else-if 语句,在保持流程控制的同时往往更易读。
一个 case 由关键字 case 定义,后面可选地跟一个表达式。
接下来,每个分支用关键字 when,后面跟一个表达式,它会与 case 表达式进行比较。
when 关键字不应相对于 case 关键字缩进。
when 关键字之后,是当 case 表达式与 when 表达式匹配时要执行的代码。
Case 允许带一个可选的 else 语句,当没有其他分支匹配时执行。
先计算 case 表达式,然后与每个 when 表达式比较。
比较使用的是 case 相等运算符(===)。
value = 1
case value
when 1
"One"
when 2
"Two"
else
"Other"
end
# This is the same as:
value = 1
if 1 === value
"One"
elsif 2 === value
"Two"
else
"Other"
end
===)case 相等运算符(===)与相等运算符(==)略有不同。
它会检查右侧是否为左侧所描述的集合的成员。
也就是说,每个操作数放在哪一侧是有影响的。
具体如何工作取决于左侧的类型,例如 Range 会检查右侧是否在范围内,而 Object 会检查右侧是否为 Object 的实例。
(1..3) == 1 # => false
(1..3) === 1 # => true
String == "foo" # => false
String === "foo" # => true
case 允许在同一个分支里匹配多个表达式,各个可能的值用逗号分隔。 只要其中任意一个表达式匹配,就会执行对应的代码。 当你希望同一个分支有多个可能的值时,这很有用。
case var
when 1, 2
"One or two"
else
"Other"
end
case 也可以检查某个值是否在一个范围内。 只需把范围作为 when 表达式即可。
case var
when 1..3
puts "One to three"
else
puts "Other"
end
如果不需要 case 表达式,可以把它省略。 这样一来,每个分支的表达式都会按真假值来判断。 使其行为与 if-else-if 语句相同。
case
when 1 == 1
"One is equal to one"
when 1 > 2
"One is greater than two"
else
"Other"
end
Ruby 允许使用单行 case 语句。
当语句很简单、只有一行时,就可以这样做。
单行 when 语句写作 when <expression> then <statement>。
用在 else 中时,写作 else <statement>。
case var
when 1 then "One"
when 2 then "Two"
else "Other"
end
case 可以按类型进行匹配。 当你想根据变量的类型做出不同行为时,这很有用。
case var
when Integer
"Integer"
when String
"String"
else
"Other"
end
在这个练习中,我们将模拟二十一点游戏的第一个回合。
你会拿到两张牌,并且能看到庄家亮出的那张明牌。 所有牌都用字符串表示,例如 “ace”、“king”、“three”、“two” 等。每张牌的点数如下:
| 牌 | 点数 | 牌 | 点数 |
|---|---|---|---|
| ace | 11 | eight | 8 |
| two | 2 | nine | 9 |
| three | 3 | ten | 10 |
| four | 4 | jack | 10 |
| five | 5 | queen | 10 |
| six | 6 | king | 10 |
| seven | 7 | 其他 | 0 |
通常,A 既可以算作 1,也可以算作 11,但为了简单起见,我们假设它只能算作 11。
实现 Blackjack.parse_card 方法,它接收一个字符串形式的牌名作为实参。
该方法应以整数形式返回这张牌的点数。
Blackjack.parse_card("ace")
# => 11
玩家的得分需要划分到不同的点数范围内。 玩家得分由两张手牌的点数相加得到。 使用的范围如下:
| 范围 | 点数 |
|---|---|
| low | [4, 11] |
| mid | [12, 16] |
| high | [17, 20] |
| blackjack | [21] |
实现 Blackjack.card_range 方法,它接收两个字符串形式的牌名作为实参。
该方法应返回这两张牌所属点数范围的名称。
Blackjack.card_range("ten", "king")
# => "high"
根据你的两张牌和庄家的明牌,游戏的第一回合有一套策略,你可以做出以下几种选择:
虽然这套策略还不是最优的,但你会采用你的朋友 Alex 一直在完善的策略,具体如下:
实现 Blackjack.first_turn 方法,它接收三个字符串形式的牌名作为实参。
该方法应以字符串形式返回你应该采取的决策。
Blackjack.first_turn("ace", "ace", "two")
# => "P"