13.md 20.6 KB
Newer Older
W
init  
wizardforcel 已提交
1 2 3 4
## 4.比较与逻辑

### 4.1。 逻辑运算符

W
wizardforcel 已提交
5
逻辑运算符使你可以确定天气是否正确。 例如,一个就是一个,那就是人类的想法,让我们看看计算机对此的想法。 发射你的 irb 并输入 1 等于 1,如图所示
W
init  
wizardforcel 已提交
6

W
wizardforcel 已提交
7
```rb
W
init  
wizardforcel 已提交
8 9 10 11 12 13
>> 1 == 1
=> true
```

好吧,那等于符号的两倍呢? 单个等于号表示分配,例如`a = 5`,将值`5`放入`a`。 双等于符号是比较。 因此,以上我们检查了 1 是否等于 1 且答案为`true`。 电脑是智能的,不是吗? OK,现在让我们检查 1 是否等于 2,所以我们输入`1==2`和...

W
wizardforcel 已提交
14
```rb
W
init  
wizardforcel 已提交
15 16 17 18 19 20 21 22
>> 1 == 2
=> false
```

计算机(在这种情况下为 Ruby 解释器)告诉计算机`false`

很好,如果在我们键入计算机时 1 与计算机不等于 2,则必须输出 true,因此请在控制台中键入

W
wizardforcel 已提交
23
```rb
W
init  
wizardforcel 已提交
24 25 26 27 28 29 30 31
>> 1 != 2
=> true
```

`!=`代表不等于。 ! 代表不

现在我们检查 1 是否不等于 1,并且计算机按预期给出`false`作为输出。

W
wizardforcel 已提交
32
```rb
W
init  
wizardforcel 已提交
33 34 35 36 37 38
>> 1 != 1
=> false
```

现在,我们检查 2 是否大于 3,对于大于,我们使用`>`符号

W
wizardforcel 已提交
39
```rb
W
init  
wizardforcel 已提交
40 41 42 43 44 45
>> 2 > 3
=> false
```

现在,我们将检查 2 是否小于 3,因为小于`<`符号

W
wizardforcel 已提交
46
```rb
W
init  
wizardforcel 已提交
47 48 49 50 51 52 53 54
>> 2 < 3
=> true
```

凉! 我们发现如果 2 不大于 3,则其小于 3。那么我们将获得数学诺贝尔奖:)

`&gt;=`代表大于或等于

W
wizardforcel 已提交
55
```rb
W
init  
wizardforcel 已提交
56 57 58 59 60 61 62 63
>> 5 >= 3
=> true
```

由于 5 大于 3,因此返回`true`

参见下面的表达式,因为 5 等于 5,它仍然返回`true`

W
wizardforcel 已提交
64
```rb
W
init  
wizardforcel 已提交
65 66 67 68 69 70
>> 5 >= 5
=> true
```

5 不大于 5,因此在下面返回 false

W
wizardforcel 已提交
71
```rb
W
init  
wizardforcel 已提交
72 73 74 75 76 77
>> 5 > 5
=> false
```

3 小于 5,因此小于或等于运算符`⇐`返回 true

W
wizardforcel 已提交
78
```rb
W
init  
wizardforcel 已提交
79 80 81 82 83 84
>> 3 <= 5
=> true
```

3 等于 3,因此小于或等于运算符仍返回 true

W
wizardforcel 已提交
85
```rb
W
init  
wizardforcel 已提交
86 87 88 89 90 91
>> 3 <= 3
=> true
```

3 不小于 3,等于 3,因此小于运算符返回`false`

W
wizardforcel 已提交
92
```rb
W
init  
wizardforcel 已提交
93 94 95 96
>> 3 < 3
=> false
```

W
wizardforcel 已提交
97
你也可以尝试使用数字
W
init  
wizardforcel 已提交
98 99 100 101 102 103 104 105 106 107

<colgroup><col style="width: 50%;"> <col style="width: 50%;"></colgroup> 
| 操作员 | 含义 |
| ! &lt; | 不小于 |
| ! &gt; | 不大于 |

他们工作吗? ;)

### 4.2。 true!=“ true”

W
wizardforcel 已提交
108
在逻辑运算符部分,你可能会看到 irb 提供`true``false`作为输出。 你不要与`“true”``“false”`混淆。 `true``false`是逻辑值,而`“true”``“false”``String`
W
init  
wizardforcel 已提交
109 110 111 112 113

### 4.3。 ===

`===`运算符用于检查特定实例 &lt;sup class="footnote"&gt;[ [12](#_footnotedef_12 "View footnote.") ]&lt;/sup&gt; 是否属于一类(即类型)。 例如,`“abc”``String`类型的对象,`1``Integer`,因此让我们在其上应用`===`并检查

W
wizardforcel 已提交
114
```rb
W
init  
wizardforcel 已提交
115 116 117 118 119 120 121 122
>> String === "abc"
=> true
>> Integer === 1
=> true
```

从上面的示例中可以看到,我们在左边有类名,在右边有实例。 前两个示例为`true`,因为`“abc”`为字符串,`1`为整数。

W
wizardforcel 已提交
123
```rb
W
init  
wizardforcel 已提交
124 125 126 127
>> String === 7
=> false
```

W
wizardforcel 已提交
128
在上面的示例中,由于`7`绝对不是`String`,因此它显然返回 false,这就是你可能会想到的;)
W
init  
wizardforcel 已提交
129 130 131

但是有些奇怪,请看下面的例子

W
wizardforcel 已提交
132
```rb
W
init  
wizardforcel 已提交
133 134 135 136 137 138 139 140 141 142
>> "abc" === String
=> false
```

因此,始终将类放在左侧,将实例放在右侧。

### 4.4。 如果

如果满足条件,则使用 if 关键字执行语句。 看看下面的程序。 执行它。

W
wizardforcel 已提交
143
```rb
W
init  
wizardforcel 已提交
144 145 146 147 148 149 150 151
# if.rb

puts "Whats your name?"
name = gets.chop
puts "#{name} is genius" if name == "Zigor"
puts "#{name} is idiot" if name != "Zigor"
```

W
wizardforcel 已提交
152
如果你输入的名称不是 Zigor,结果将会是这样
W
init  
wizardforcel 已提交
153

W
wizardforcel 已提交
154
```rb
W
init  
wizardforcel 已提交
155 156 157 158 159 160 161
Whats your name?
Karthik
Karthik is idiot
```

看一下程序。 看一下下面这行

W
wizardforcel 已提交
162
```rb
W
init  
wizardforcel 已提交
163 164 165
puts "#{name} is genius" if name == "Zigor"
```

W
wizardforcel 已提交
166
该程序在名为`name`的变量中获取你的名字。 现在,它检查上面代码中名称是否为 Zigor(在关键字`if`的右侧),如果是,则执行与之关联的语句(即关键字`if`的左侧的语句) ),在这种情况下,它会打印出特定的名称是 genius。 然后归结为下一条语句
W
init  
wizardforcel 已提交
167

W
wizardforcel 已提交
168
```rb
W
init  
wizardforcel 已提交
169 170 171 172 173 174 175 176 177
puts "#{name} is idiot" if name != "Zigor"
```

在此语句中,它检查名称是否不是 Zigor,如果是,则打印名称为 idiot。

### 4.5。 如果别的

让我们以另一种形式编写 who genius 程序,这里我们使用 if else 条件代替`if`。 看一下下面的名为 if_else.rb 的代码

W
wizardforcel 已提交
178
```rb
W
init  
wizardforcel 已提交
179 180 181 182 183 184 185 186 187 188 189 190
# Zigor says if the person is intelligent or not
print "Enter your name: "
name = gets.chop
if name == "Zigor"
  puts "#{name} is intelligent"
else
  puts "#{name} is idiot"
end
```

程序在执行时会提供与先前的 if.rb 相同的输出,不同之处在于程序内部逻辑的表示方式。 我们看到一个叫做`if name == "Zigor"`的东西,然后在代码正确的情况下执行该操作,如图所示

W
wizardforcel 已提交
191
```rb
W
init  
wizardforcel 已提交
192 193 194 195 196 197
if name == "Zigor"
  puts "#{name} is intelligent"
```

现在,我们可以在之后放置任意数量的语句,如果满足给定的条件,则所有语句将被执行。 到目前为止,还不错,但是 Ruby 如何知道 if 语句在哪里结束呢? 为了说到此为止,我们如下所示放置了`end`关键字。

W
wizardforcel 已提交
198
```rb
W
init  
wizardforcel 已提交
199 200 201 202 203 204 205
if name == "Zigor"
  puts "#{name} is intelligent"
end
```

假设`if`中给出的条件不满足,我们需要做一些`if`条件无效的操作,然后将条件失败时执行的语句放在`else`关键字下,如下所示

W
wizardforcel 已提交
206
```rb
W
init  
wizardforcel 已提交
207 208 209 210 211 212 213 214 215
if name == "Zigor"
  puts "#{name} is intelligent"
else
  puts "#{name} is idiot"
end
```

请注意,`else`和条件失败时需要执行的语句位于`end`语句之前。 结束标记`if else`块的结束。 不一定总是需要其他,而是可以有一个如下所示的代码

W
wizardforcel 已提交
216
```rb
W
init  
wizardforcel 已提交
217 218 219 220 221
if <condition>
  # many lines of code goes here
end
```

W
wizardforcel 已提交
222
在上面,你可以在`if … end`块中放入许多需要执行的代码。
W
init  
wizardforcel 已提交
223 224 225 226 227

### 4.6。 埃尔斯夫

当我们使用`if``else`时,如果满足条件,则将执行`if`下的代码,否则将执行`else`部分下的代码。 让我们有一个新的场景,其中`if`下的代码不满足,然后程序立即跳转到`else`部分,现在逻辑要求我们也需要在`else`级别检查另一个条件,我们应该怎么做? 做? 为了应对这种情况,我们可以使用`elsif`命令。 看看下面的代码

W
wizardforcel 已提交
228
```rb
W
init  
wizardforcel 已提交
229 230 231 232 233 234 235 236 237 238 239 240 241 242 243
# elsif.rb
# finds the greatest of three numbers

a,b,c = 3,7,5

if a >= b and a >= c
  puts "a = #{a} is greatest"
elsif b >= c and b >= a
  puts "b = #{b} is greatest"
else puts "c = #{c} is greatest"
end
```

执行后会产生以下结果

W
wizardforcel 已提交
244
```rb
W
init  
wizardforcel 已提交
245 246 247 248 249
b = 7 is greatest
```

让我们逐步浏览代码。 让我们看看这条线

W
wizardforcel 已提交
250
```rb
W
init  
wizardforcel 已提交
251 252 253 254 255
a,b,c = 3,7,5
```

在这一行中,我们为变量`a,b``c`分配值 3、7 和 5。 现在来看 if 语句

W
wizardforcel 已提交
256
```rb
W
init  
wizardforcel 已提交
257 258 259 260 261
if a > b and a > c
```

在此语句中,我们检查`a`是否大于`b``a`是否大于`c`。 注意关键字`and`。 仅当两个条件都为真时,才满足`if`条件。 `a`小于`b`,因此此条件失败,因此程序跳过`if`语句并进入`elsif`语句

W
wizardforcel 已提交
262
```rb
W
init  
wizardforcel 已提交
263 264 265 266 267
elsif b > c and b > a
```

`elsif``else``if`,在这里我们检查由`and`分隔的另外两个条件,我们检查`b `is greater than `a``b`是否大于`c`,两者均为真,因此 `elsif`下的声明

W
wizardforcel 已提交
268
```rb
W
init  
wizardforcel 已提交
269 270 271 272 273 274 275 276 277
puts "b = #{b} is greatest"
```

得到执行,我们得到结果。 由于`elsif`满足其他`else`的要求,并且其下的代码也将被忽略。

### 4.7。 如果那样的话

还有另一个条件构造,它的 if 称为 if then else,它与 if else 并没有太大区别,下面出于理论目的显示了一个示例,就我个人而言,它并没有任何实际目的,但是出于理论上的考虑 将示例放在下面,执行并亲自查看。

W
wizardforcel 已提交
278
```rb
W
init  
wizardforcel 已提交
279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294
#if_then_else.rb

number = 42

if number % 2 == 0
  then
  puts "Even"
  else
    puts "Odd"
end
```

### 4.8。 除非

除非是检查状况的另一种方法。 假设一个人是未成年人,除非他或她大于 18 岁。 那么如何在 Ruby 中编码呢? 考虑下面的程序,在文本编辑器中键入并执行它。

W
wizardforcel 已提交
295
```rb
W
init  
wizardforcel 已提交
296 297 298 299 300 301 302 303
# unless.rb
print "Enter your age:"
age = gets.to_i
p "You are a minor" unless age >= 18
```

执行后,这就是我们得到的

W
wizardforcel 已提交
304
```rb
W
init  
wizardforcel 已提交
305 306 307 308
Enter your age:16
"You are a minor"
```

W
wizardforcel 已提交
309
程序会询问你的年龄,如果年龄不大于 18,则表示你是未成年人。也就是说,除非你的年龄大于或等于 18(如在此情况下所示),否则你将是未成年人`unless age &gt;= 18``p`是看跌期权 &lt;sup class="footnote"&gt;[ [13](#_footnotedef_13 "View footnote.") ]&lt;/sup&gt; 的简称。 如果编写`puts “something”`,则红宝石解释程序将打印`something`。 如果你使用`p ”something”`,则红宝石解释器将打印`”something”`(这与这些引号一起使用)。
W
init  
wizardforcel 已提交
310 311 312

如果我们想在`unless`块下放置多行代码,可以使用`unless …​. end`块,如下所示

W
wizardforcel 已提交
313
```rb
W
init  
wizardforcel 已提交
314 315 316 317 318 319 320 321 322 323 324
unless <condition>
  # many lines of code goes here
end
```

如果`&lt;condition&gt;`失败,则执行块中的代码。 可以认为`unless``if`相反。 如果 if 块被执行`if`的条件是`true`,则`unless`块被执行的条件是`false`

### 4.9。 除非另有

就像`if``else`一样,我们可以在`unless`语句中使用`else`。 输入以下程序并执行

W
wizardforcel 已提交
325
```rb
W
init  
wizardforcel 已提交
326 327 328 329 330 331 332 333 334 335 336
# unless_1.rb
print "Enter your age:"
age = gets.to_i
unless age >= 18
  p "You are a minor"
  else p "You are a grown up"
end
```

这是执行时得到的

W
wizardforcel 已提交
337
```rb
W
init  
wizardforcel 已提交
338 339 340 341
Enter your age:37
"You are a grown up"
```

W
wizardforcel 已提交
342
好的,这是它的工作原理,你可以确定年龄,将其转换为`age = gets.to_i`中的整数,并将其存储在名为`age`的变量中。 专注于这段代码:
W
init  
wizardforcel 已提交
343

W
wizardforcel 已提交
344
```rb
W
init  
wizardforcel 已提交
345 346 347 348 349 350 351 352 353 354
unless age >= 18
  p "You are a minor"
  else p "You are a grown up"
end
```

除非`age`小于 18 `“You are a minor”`不会被打印出来。 如果年龄大于或等于 18,则将其路由到`else`语句,并打印`“You are a grown up”`。 请注意,如果将`else``unless`一起使用,则必须使用`end`命令终止`unless`块。

现在让我们看一下另一个使用`unless else`的程序。 我们想招募人员来武装,这个人应该在 18 到 35 岁之间,我们的计划向想要入学的人询问详细信息,检查其年龄并告知结果。 在下面输入程序并执行

W
wizardforcel 已提交
355
```rb
W
init  
wizardforcel 已提交
356 357 358 359 360 361 362 363 364 365 366
# unless_2.rb
print "Enter your age:"
age = gets.to_i
unless age < 18 or age > 35
  p "You can enter Armed forces"
  else p "You cannot enter Army. You are either too young or too old"
end
```

执行时将是结果

W
wizardforcel 已提交
367
```rb
W
init  
wizardforcel 已提交
368 369 370 371
Enter your age:23
"You can enter Armed forces"
```

W
wizardforcel 已提交
372
我认为你可以自行解释该程序。 如果没有其他联系方式,除非我很懒,否则我会写一个解释。
W
init  
wizardforcel 已提交
373 374 375

### 4.10。 情况何时

W
wizardforcel 已提交
376
假设你要编写一个程序,该程序对于确定的输入具有确定的输出,则可以在以下情况下使用这种情况。 假设我们要编写一个拼写为 1 到 5 的程序,我们可以按照 code / case_when.rb [case_when.rb]中所示的方法进行操作,在文本编辑器中键入该程序并执行。
W
init  
wizardforcel 已提交
377

W
wizardforcel 已提交
378
```rb
W
init  
wizardforcel 已提交
379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405
# case_when.rb
# This program spells from one to five

print "Enter a number (1-5):"
a = gets.to_i
spell = String.new

case a
  when 1
    spell = "one"
  when 2
    spell = "two"
  when 3
    spell = "three"
  when 4
    spell = "four"
  when 5
    spell = "five"
  else
    spell = nil
end

puts "The number you entered is "+spell if spell
```

输出量

W
wizardforcel 已提交
406
```rb
W
init  
wizardforcel 已提交
407 408 409 410 411 412
Enter a number (1-5):4
The number you entered is four
```

让我们看看上面的程序是如何工作的。 首先,提示用户输入数字,当他输入数字时,在以下语句中将其从字符串转换为整数

W
wizardforcel 已提交
413
```rb
W
init  
wizardforcel 已提交
414 415 416 417 418
a = gets.to_i
```

变量`a`现在包含我们输入的数字的值,我们具有`case`语句,如下所示

W
wizardforcel 已提交
419
```rb
W
init  
wizardforcel 已提交
420 421 422 423 424 425 426
case a
  ......
end
```

在上面的空 case 语句中,我们将编写根据`a`的值执行的代码。 当`a`为 1 时,我们需要将其拼写为`“one”`,因此我们添加以下代码

W
wizardforcel 已提交
427
```rb
W
init  
wizardforcel 已提交
428 429 430 431 432 433 434 435
case a
  when 1
  spell = "one"
end
```

同样,我们添加代码直到大小写为 5,如图所示

W
wizardforcel 已提交
436
```rb
W
init  
wizardforcel 已提交
437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452
case a
  when 1
  spell = "one"
  when 2
  spell = "two"
  when 3
  spell = "three"
  when 4
  spell = "four"
  when 5
  spell = "five"
end
```

在某些情况下,运行此程序的人员可能会输入错误的信息,因此我们也需要处理这些情况。 为此,我们添加了一个名为`else`的特殊语句,如果所有情况都失败了,则执行 else 下的代码,但是必须注意,在`case … end`块之间没有`else`是强制性的。 所以现在程序更改如下所示

W
wizardforcel 已提交
453
```rb
W
init  
wizardforcel 已提交
454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471
case a
  when 1
  spell = "one"
  when 2
  spell = "two"
  when 3
  spell = "three"
  when 4
  spell = "four"
  when 5
  spell = "five"
  else
  spell = nil
end
```

接下来,我们要做的就是打印出`spell`,我们在以下语句中这样做

W
wizardforcel 已提交
472
```rb
W
init  
wizardforcel 已提交
473 474 475 476 477 478 479
puts "The number you entered is "+spell if spell
```

请注意,仅当`spell`包含值时才打印,否则,如果`spell``nil`,则不打印任何内容。 上面声明中的`if`条件要小心。

有时可能有必要针对许多条件执行同一组语句。 让我们以一个示例应用程序为例,在该应用程序中,程序确定 1 到 10(包括两者)之间的数字是奇数或偶数。 键入下面的代码(code / case_odd_even.rb [case_odd_even.rb])并执行

W
wizardforcel 已提交
480
```rb
W
init  
wizardforcel 已提交
481 482 483 484 485 486 487 488 489 490 491 492 493 494
# case_odd_even.rb

num = 7 # put any number from 1 to 10

case num
  when 1, 3, 5, 7, 9
    puts "#{num} is odd"
  when 2, 4, 6, 8, 10
    puts "#{num} is even"
end
```

Output

W
wizardforcel 已提交
495
```rb
W
init  
wizardforcel 已提交
496 497 498
7 is odd
```

W
wizardforcel 已提交
499
注意,在上面的程序中,我们为变量`num`分配了值 7,接下来,我们将`num`放入`case`语句中。 当数字为 1、3、5、7 和 9 时,我们需要打印其奇数,因此我们要做的只是对个案进行分组。 如果满意,则必须将其打印为`odd`,如果你按照下面的代码所示放置,就足够了
W
init  
wizardforcel 已提交
500

W
wizardforcel 已提交
501
```rb
W
init  
wizardforcel 已提交
502 503 504 505 506 507 508 509
case num
  when 1, 3, 5, 7, 9
  puts "#{num} is odd"
end
```

接下来,我们只需要打印数字,即使该数字是 2、4、6、8 和 10,要做到这一点,我们要做的就是添加下面突出显示的代码

W
wizardforcel 已提交
510
```rb
W
init  
wizardforcel 已提交
511 512 513 514 515 516 517 518 519 520 521 522 523 524
case num
  when 1, 3, 5, 7, 9
  puts "#{num} is odd"
  when 2, 4, 6, 8, 10
  puts "#{num} is even"
end
```

而已。 该代码适用于从 1 到 10 的所有数字。故事的寓意是,我们可以轻松地将案例分组并在其中执行通用代码。

### 4.11。 情况下,检查类类型

在 Ruby 中,一切都是对象。 让我们在 irb 中尝试一些例子来证明这一点

W
wizardforcel 已提交
525
```rb
W
init  
wizardforcel 已提交
526 527 528 529 530 531
>> 1.class
=> Integer
>> "Zigor".class
=> String
```

W
wizardforcel 已提交
532
在第一条语句中,我们查询了`1`的类/对象类型,并说其类型为`Integer`。 当被问及`“Zigor”`的类别时,它说`String`。 在 Ruby 中,你可以使用此函数来了解所使用的类型变量。 它是一个非常强大的功能。
W
init  
wizardforcel 已提交
533 534 535

现在看看下面的程序

W
wizardforcel 已提交
536
```rb
W
init  
wizardforcel 已提交
537 538 539 540 541 542 543 544 545 546 547 548
# case_when_checking_class_type.rb
a = "Zigor"
case a
when String
  puts "Its a string"
when Fixnum
  puts "Its a number"
end
```

Output

W
wizardforcel 已提交
549
```rb
W
init  
wizardforcel 已提交
550 551 552 553 554 555 556 557 558 559 560 561 562
Its a string
```

参见上面程序中的行,我们有两个语句,例如`when String``when Integer`,这将检查`case a`语句中变量`a`的类型。 如果变量类型为`String`,它将在`when String`事物下执行语句,而当其为`Integer`时,将执行另一个语句。 由于此`a`是 String 类型的,因此我们得到了打印输出`Its a String`

### 4.12。 情况和范围

请检查以防万一。

### 4.13。 情况以及正则表达式

Case 语句也可以匹配正则表达式。 阅读正则表达式部分以了解以下示例。

W
wizardforcel 已提交
563
```rb
W
init  
wizardforcel 已提交
564 565 566 567 568 569 570 571 572 573 574 575 576 577 578
# case_when_regexp.rb

string = "I Love Ruby"
# string = "I Love Python"

case string
when /Ruby/
  puts "string contains Ruby"
else
  puts "string does not contain Ruby"
end
```

Output

W
wizardforcel 已提交
579
```rb
W
init  
wizardforcel 已提交
580 581 582 583 584 585 586 587 588
string contains Ruby
```

在上面的示例中,检查语句`when /Ruby/`,它会检查表达式`/Ruby/`出现在`string`中。 在上面的示例中,它确实出现了。 因此它打印出`string contains Ruby`

### 4.14。 情况何时和 lambdas

[case_odd_even.rb](code/case_odd_even.rb) 中,当我们尝试检查数字是否为奇数或偶数时,我们给出了一个冗长的程序,其范围限制为 1 到 10 之间的数字。 我们可以编写如下所示的相同程序

W
wizardforcel 已提交
589
```rb
W
init  
wizardforcel 已提交
590 591 592 593 594 595 596 597 598 599 600 601 602 603
# case_odd_even_lambda.rb

num = 76

case num
when -> (n) { n % 2 == 0 }
  puts "#{num} is even"
else
  puts "#{num} is odd"
end
```

Output

W
wizardforcel 已提交
604
```rb
W
init  
wizardforcel 已提交
605 606 607
76 is even
```

W
wizardforcel 已提交
608
要理解以上示例,你必须先阅读 Proc,Lambda 和 Blocks。 观看代码`when → (n) { n % 2 == 0 }`,在其中将一个 lambda 传递给`when`,当调用该代码时,它将为`n`的值 76 或任何偶数返回`true`,如果`n`为奇数则返回`false` 。 因此,与以前的奇偶程序不同,它适用于从零到无限的所有自然数。
W
init  
wizardforcel 已提交
609 610 611

### 4.15。 case 和 matcher 类的情况

W
wizardforcel 已提交
612
要了解下面的程序,你需要阅读===并检查案例类型时的大小写。 在下面输入程序并执行
W
init  
wizardforcel 已提交
613

W
wizardforcel 已提交
614
```rb
W
init  
wizardforcel 已提交
615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634
# case_when_matcher_classes.rb

class Zigor
  def self.===(string)
    string.downcase == "zigor"
  end
end

name = "Zigor"

case name
when Zigor
  puts "Nice to meet you Zigor!!!"
else
  puts "Who are you?"
end
```

Output

W
wizardforcel 已提交
635
```rb
W
init  
wizardforcel 已提交
636 637 638 639 640
Nice to meet you Zigor!!!
```

考虑这一部分

W
wizardforcel 已提交
641
```rb
W
init  
wizardforcel 已提交
642 643 644 645 646 647 648 649 650 651
case name
when Zigor
  puts "Nice to meet you Zigor!!!"
else
  puts "Who are you?"
end
```

`case`语句检查`name`并查看其实例类型是否为`Zigor`。 嗯,这并不奇怪吗? 怎么可能 属于`String`类的一个实例如何变为`Zigor`类的一个实例? 好吧,情况是什么,它调用了`Zigor`类中的`===`方法,其定义可以在 &lt;sup class="footnote"&gt;[ [14](#_footnotedef_14 "View footnote.") ]&lt;/sup&gt; 下看到。

W
wizardforcel 已提交
652
```rb
W
init  
wizardforcel 已提交
653 654 655 656 657 658 659
def self.===(string)
  string.downcase == "zigor"
end
```

在这里我们定义`self.===`,在其中接受一个参数字符串,在这里传递给`case``name`被复制到`string`,并检查`string``downcase`是否等于`“zigor”``string.downcase == "zigor"`中,如果是,则返回`true`,否则返回`false`。 如果`true`被执行,当 when Zigor 块中的代码被执行时,我们得到输出`Nice to meet you Zigor!!!`。 将名称更改为其他值,然后看看会发生什么。

W
wizardforcel 已提交
660
如果你现在不了解此章节,请不要担心。 在完成本书的复习之后,你可能会更好地理解它。
W
init  
wizardforcel 已提交
661 662 663 664 665

### 4.16。 ? :

`? :`被称为三元运算符。 它可以用作简单的`if`。 请执行以下所示的程序。 专心`max = a &gt; b ? a : b`

W
wizardforcel 已提交
666
```rb
W
init  
wizardforcel 已提交
667 668 669 670 671 672 673 674 675
# max_of_nums.rb

a,b = 3,5
max = a > b  ? a : b
p "max = "+max.to_s
```

执行后,程序给出以下输出

W
wizardforcel 已提交
676
```rb
W
init  
wizardforcel 已提交
677 678 679 680 681
"max = 5"
```

?:的工作原理如下。 它的语法是这样的

W
wizardforcel 已提交
682
```rb
W
init  
wizardforcel 已提交
683 684 685
<evaluate something > ? <if true take this thing> : <if false take this thing>
```

W
wizardforcel 已提交
686
你在问号之前给出一个表达式。 该表达式必须返回`true``false`。 如果表达式返回 true,则`it`返回`?``:`之间的内容;如果`false`,则返回`:`之后的内容。
W
init  
wizardforcel 已提交
687 688 689

在表达中

W
wizardforcel 已提交
690
```rb
W
init  
wizardforcel 已提交
691 692 693 694 695
max = a > b  ? a : b
```

我们可以如下替换`a``b`的值

W
wizardforcel 已提交
696
```rb
W
init  
wizardforcel 已提交
697 698 699 700 701 702 703
max = 3 > 5  ? 3 : 5
```

3 不大于 5,因此其`false`。 因此,将`:`之后的值分配给`max`。 因此,`max`变为 5。

### 4.17。 将逻辑语句分配给变量

W
wizardforcel 已提交
704
不管你是否注意到了天气,在前面的示例 [max_of_nums.rb](code/max_of_nums.rb) 中,我们使用了这样的语句
W
init  
wizardforcel 已提交
705

W
wizardforcel 已提交
706
```rb
W
init  
wizardforcel 已提交
707 708 709 710 711 712 713
max = a > b  ? a : b
```

这里`a &gt; b`是逻辑,如果它的`true`它将返回`a`,该`a`被分配给`max`,或者它返回`b`,其被分配给`max`

现在相同的程序可以编写如下

W
wizardforcel 已提交
714
```rb
W
init  
wizardforcel 已提交
715 716 717 718 719 720 721 722 723 724 725 726 727
# max_of_nums_with_if.rb

a, b = 3, 5
max = if a > b
  a
else
  b
end
p "max = " + max.to_s
```

Output

W
wizardforcel 已提交
728
```rb
W
init  
wizardforcel 已提交
729 730 731 732 733 734 735
"max = 5"
```

此处将变量`max`分配给`if`条件。 因此,如果`a`大于`b`,则会将`a`放入`max`,否则会将`b`放入`max`。 就如此容易。

现在还有另一件事。 如果`if``else`下还有其他语句怎么办? 由于在此代码块中

W
wizardforcel 已提交
736
```rb
W
init  
wizardforcel 已提交
737 738 739 740 741 742 743 744 745
max = if a > b
  a
else
  b
end
```

`if`块下只有一个语句`a`,在`else`块下我们只有`b`,所以它很简单。 现在让我们尝试下面给出的示例

W
wizardforcel 已提交
746
```rb
W
init  
wizardforcel 已提交
747 748 749 750 751 752 753 754 755 756 757 758 759 760 761
# max_of_nums_with_if_many_statements.rb

a,b = 3,5
max = if a > b
  a + b
  a
else
  a - b
  b
end
p "max = "+max.to_s
```

运行上面的程序,这就是你得到的

W
wizardforcel 已提交
762
```rb
W
init  
wizardforcel 已提交
763 764 765
"max = 5"
```

W
wizardforcel 已提交
766
那么要推断什么呢? 规则是这样的,如果你在一个块中给出许多语句并将其分配给一个变量,则最后一条语句的输出将被返回并将被放入变量 &lt;sup class="footnote"&gt;[ [15](#_footnotedef_15 "View footnote.") ]&lt;/sup&gt; (在这种情况下为最大值)。
W
init  
wizardforcel 已提交
767

W
wizardforcel 已提交
768
这是另一个程序, [case_when.rb](code/case_when.rb) 的分支,我想你知道它现在如何工作
W
init  
wizardforcel 已提交
769

W
wizardforcel 已提交
770
```rb
W
init  
wizardforcel 已提交
771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796
# case_when_2.rb
# This program spells from one to five

print "Enter a number (1-5):"
a = gets.to_i
spell = String.new

spell = case a
  when 1
    "one"
  when 2
    "two"
  when 3
    "three"
  when 4
    "four"
  when 5
    "five"
  else
    nil
end

puts "The number you entered is " + spell if spell
```

运行并亲自查看。