在 crystal 为什么我需要做 matches.try &.[0]

In crystal Why do I need to do matches.try &.[0]

这是一些代码:

matches =  /\/([a-z]+)\/(\d+)\/state\/([a-z]+)/.match(address) # line 1
puts matches[0]?                                               # line 2
puts matches.try &.[0]                                         # line 3
根据 typeof

matches 数据类型为 (Regex::MatchData | Nil)。然而,第 2 行引用 matches[0] 失败并出现编译错误。而且我根本不明白第 3 行!

有人可以澄清一下吗?

第2行:正如你所说,matches的类型是(Regex::MatchData | Nil)。万一它碰巧是 nil,它就不会有 #[]? 方法,这会让类型检查器生气。您应该首先检查 match 是否成功:

matches =  /\/([a-z]+)\/(\d+)\/state\/([a-z]+)/.match(address)
if matches
  puts matches[0]?
end

if里面,matches的类型就是Regex::MatchData(因为我们排除了Nil的可能性),类型检查器可以高枕无忧了。

如果您确定您的字符串会匹配,您可以使用 not_nil! 安抚类型检查器,但是如果您对数据一致性的信心是没有根据的,那么这可能会导致运行时错误:

puts matches.not_nil![0]?

第 3 行:#try 将执行块,除非调用者是 nil,当它 returns nil 时除外。不需要守卫,因为 #tryNil(以及 Object)上明确定义。

它对块使用 shortcut syntax,其中 &.[0] 相当于 { |x| x[0] }