首页 > 解决方案 > 在水晶中为什么我需要做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

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

有人可以澄清一下吗?

标签: crystal-lang

解决方案


第 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,当它返回时nil。不需要警卫,因为#try已明确定义 on Nil(以及 on Object)。

它使用块的快捷语法,其中&.[0]有点等价于{ |x| x[0] }.


推荐阅读