轨道
/
Crystal
Crystal
/
练习
/
应对熔毁
应对熔毁

应对熔毁

学习练习

简介

Crystal 中有所谓的控制表达式,它们用来控制程序的运行方式,并且会取一个真值或假值。 有一些运算符可以用来产生真值或假值,它们被称为相等与比较运算符。

有两种主要的控制表达式,用来控制哪些代码会运行、哪些不会。 也就是决定具体哪个分支会运行。

这两种分别是:if 和 unless 表达式。

比较运算符

比较运算符用来比较值,并返回一个 true 或 false 值。 这些运算符要求被比较的两个值类型相同。 如果两个值的类型不同,编译器就会抛出错误。 下面是比较运算符的列表,以及它们返回 true 时的示例:

方法 说明 示例
< 小于 4 < 5
<= 小于或等于 4 <= 4
> 大于 3 > 1
>= 大于或等于 2 >= 2

相等运算符

相等运算符与比较运算符类似,但用来检查两个值是否相等。

== 运算符检查两个值是否相等,包括值的类型。 如果两个值相同,就返回 true,否则返回 false。 == 运算符可以把任意类型的值与任意其他类型的值进行比较。 != 的工作方式相同,只不过当两个值不相等时返回 true,相等时返回 false。

if 语句

if 语句用来检查给定的条件是真值还是假值。 如果条件是真值,if 语句内部的代码就会运行。 if 语句以 end 关键字结尾。

if 1 == 1
  puts "1 is equal to 1"
end
# => 1 is equal to 1

if 1 > 2
  puts "1 is greater than 2"
end
# => no output

unless 语句

unless 语句的工作方式与 if 语句非常相似,但当条件为假值时,它会运行 unless 语句内部的代码。

unless 1 == 1
  puts "1 is not equal to 1"
end
# => no output

unless 1 > 2
  puts "1 is not greater than 2"
end
# => 1 is not greater than 2

else 语句

else 语句可以配合 if 和 unless 语句使用。 如果 if 分支或 unless 分支没有执行,就会执行 else 语句。

尽管 `else` 分支可以配合 `unless,` 使用,但不建议这样做,因为会影响可读性。
更好的做法是使用 `if !condition` 搭配 else 分支。
if 1 == 1
  puts "1 is equal to 1"
else
  puts "1 is not equal to 1"
end
# => 1 is equal to 1

unless 1 < 2
  puts "1 is not greater than 2"
else
  puts "1 is greater than 2"
end
# => 1 is greater than 2

“级联 if”语句

elsif 语句可以配合 if 语句使用。 如果 if 分支没有执行,并且 elsif 语句的条件为真值,就会执行 elsif 语句。 elsif 语句可以串联起来,第一个为真值的条件会被执行。 if 语句的末尾还可以有一个 else 语句,当之前所有语句的条件都不为真时,它就会运行。

if 1 != 1
  puts "1 is not equal to 1"
elsif 1 > 2
  puts "1 is greater than 2"
else
  puts "1 is not equal to 1 and 1 is not greater than 2"
end
# => 1 is not equal to 1 and 1 is not greater than 2

条件语句中的类型

当变量在不同分支中被赋值为不同类型时,它会同时带有这两种类型。 这是因为编译器不知道哪个分支会被执行。 这种多重赋值也被称为联合类型,会在后面的概念中讲解。 下面的示例展示了这一点:

if 1 == 1
  a = 1
else
  a = "1"
end

typeof(a) # => Int32 | String

三元运算符

Crystal 有一个三元运算符,也就是单行的 if-else 语句:condition ? expression_if_truthy : expression_if_falsey

1 == 1 ? puts("1 is equal to 1") : puts("1 is not equal to 1")
# => 1 is equal to 1

说明

在这个练习中,我们将为一个核反应堆开发一套简单的控制系统。

反应堆要产生功率,就必须处于临界状态。 如果反应堆的状态低于临界,它就可能受损。 如果反应堆的状态超过临界,它就可能过载并导致熔毁。 我们要降低熔毁的可能性,并正确地管理反应堆状态。

下面三个任务都与编写代码维护理想反应堆状态有关。

1. 检查临界状态

控制系统要做的第一件事,是检查反应堆是否处于临界平衡状态。 如果反应堆满足以下条件,就称它是临界的:

  • 温度低于 800 K。
  • 每秒发射的中子数大于 500。
  • 温度与每秒发射中子数的乘积小于 500000。

实现方法 Reactor.criticality_balanced?,它接收以开尔文为单位的 temperature和 neutrons_emitted 作为形参,如果满足临界条件就返回 true,否则返回 false。

Reactor.criticality_balanced?(750, 600)
# => true

2. 确定功率输出范围

反应堆一旦开始产生功率,就需要确定它的效率。 效率可以分为 4 个区间:

  1. green -> 效率不低于 80%,
  2. orange -> 效率低于 80%,但不低于 60%,
  3. red -> 效率低于 60%,但仍不低于 30%,
  4. black -> 效率低于 30%。

百分比值可以用 (generated_power/theoretical_max_power)*100 计算,其中 generated_power = voltage * current。 请注意,百分比值通常不是整数,所以要确保正确使用 < 和 <= 比较。

实现方法 Reactor.reactor_efficiency,它有三个形参:voltage、current和 theoretical_max_power。 这个方法应返回反应堆的效率区间:"green"、"orange"、"red" 或 "black"。

Reactor.reactor_efficiency(200,50,15000)
# => "orange"

3. 故障安全机制

你的最后一个任务是创建一个故障安全机制,以避免过载和熔毁。 这个机制将判断反应堆低于、等于还是高于理想临界阈值。 之后就可以通过向反应堆中插入(或取出)控制棒来提升、降低或停止临界状态。

实现方法 Reactor.fail_safe(),它接收 3 个形参:以开尔文为单位的 temperature、neutrons_produced_per_second和 threshold,并输出反应堆的状态码。

  • 如果 temperature * neutrons_produced_per_second小于 threshold 的 90%,就输出状态码 "LOW",表示必须取出控制棒才能产生功率。

  • 如果 temperature * neutrons_produced_per_second在 threshold 的正负 10% 范围内,反应堆就处于临界状态,应输出状态码 "NORMAL",表示反应堆处于最佳状态,控制棒处于理想位置。

  • 如果 temperature * neutrons_produced_per_second不在上述范围内,反应堆正在走向熔毁,必须输出状态码 "DANGER",以立即关闭反应堆。

temperature = 1000
neutrons_produced_per_second = 30
threshold = 5000
Reactor.fail_safe(temperature, neutrons_produced_per_second, threshold)
# => "DANGER"
通过 GitHub 编辑 链接将在新窗口或新标签页中打开
Crystal Exercism

准备好开始 应对熔毁 了吗?

注册 Exercism,借助 26 个概念142 个练习 和真人导师指导,学习并掌握 Crystal,全部免费。