在 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
时除外。不需要守卫,因为 #try
在 Nil
(以及 Object
)上明确定义。
它对块使用 shortcut syntax,其中 &.[0]
相当于 { |x| x[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
时除外。不需要守卫,因为 #try
在 Nil
(以及 Object
)上明确定义。
它对块使用 shortcut syntax,其中 &.[0]
相当于 { |x| x[0] }
。