轨道
/
Crystal
Crystal
/
练习
/
城堡晚宴
城堡晚宴

城堡晚宴

学习练习

简介

Crystal 有一种类型叫做Nil,它只能有一个值:nil。 它用来表示值的缺失,类似于其他语言中的null或None。

许多方法都可能返回 Nil 值,例如String#[]?,当索引越界时它会返回nil。

"foo"[10]? # => nil

Crystal 有所谓的空引用检查,这意味着默认情况下所有类型都不能为 nil。 也就是说,除非你显式地把变量声明为Nil类型,否则不能把nil赋给它。 反过来,这意味着编译器会自动检查空引用。

假值

处理nil值有几种办法。 nil和false一样,都是假值。 这意味着,在语句以及其他需要真值或假值的地方,它都会被当作false来处理。

if nil
  puts "nil is truthy"
else
  puts "nil is falsey"
end

# => nil is falsey

这意味着,如果一个可为 nil 的变量的值是nil,就不会进入真值分支。

foo = "boo"[2]? # It is possible that foo is nil
if foo
  p foo.class # => Char
end

检查是否为 nil

Crystal 有一个方法可以用来检查某个值是否为nil。 它叫做nil?,所有对象都可以使用。

foo = "boo"[2]?
if foo.nil?
  puts "foo is nil"
else
  puts "foo is not nil"
end

如果只是把这个值用在if语句里,情况会有些不同:在上面的例子里,false和nil都会被当作假值。 而在这里,只有nil会被当作假值,因为如果它是false,那它就不是nil,因此会是真值。

or 运算符

处理nil值最简单的办法,就是从一开始就确保它们不会变成nil。 or 运算符(||)常用于处理Bools,但只要理解正确,它也可以用来处理nil值。 or 运算符会检查第一个值是否为真值,如果不是,就使用第二个值。 这样,如果值是nil,它就是假值,于是会使用第二个值。

"foo"[10]? || "bar" # => "bar"

说明

陛下将在卡尔马联盟的首都哥本哈根举办一场晚宴。 这是全年最盛大的宴会,所有贵族都在受邀之列。 但全国各地都在流传谣言,说有人密谋毒害陛下。

陛下请你这位皇家验毒师查明,是否有食物或饮料被下了毒。 陛下计划只供应Mushroom pasties作为食物,但饮料则多种多样。

1. 检查食物是否正确

如果食物不是陛下点的,就极有可能被下了毒。如果食物不是陛下点的,就应该扔掉。

实现check_food?方法,它接受实参food,其中是以String表示的食物名称。 如果食物是Mushroom pasties,方法应返回该食物;否则应返回nil。

CastleDinner.check_food?("Mushroom pasties")
# => "Mushroom pasties"

CastleDinner.check_food?("Bread")
# => nil

2. 检查饮料是否有毒

饮料有可能被下了毒,但判断起来要稍微困难一些。 如果饮料名称中不包含字母i,就说明它被下了毒,大小写不限。 如果饮料被下了毒,就应该扔掉。

实现check_drink?方法,它接受实参drink,其中是以String表示的饮料名称。 如果饮料没有被下毒,方法应返回该饮料,否则应返回nil。

CastleDinner.check_drink?("Apple juice")
# => "Apple juice"

CastleDinner.check_drink?("Tea")
# => nil

3. 更换饮料

陛下不希望让宾客担心食物里有毒。 因此,如果饮料被下了毒,就应该换成一款新的饮料,也就是Apple juice。

实现replace_drink方法,它接受实参drink,其中是以String表示的饮料名称。 如果饮料没有被下毒,方法应返回该饮料,否则应返回"Apple juice"。

CastleDinner.replace_drink("Orange juice")
# => "Orange juice"

CastleDinner.replace_drink("Tea")
# => "Apple juice"
通过 GitHub 编辑 链接将在新窗口或新标签页中打开
Crystal Exercism

准备好开始 城堡晚宴 了吗?

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