我有一个名为current_todos
的字符串数组,并试图通过执行以下操作添加一个类型为(String | Nil)
、名为new_task
的变量:
current_todos << new_task if typeof(new_task) == String
我得到错误Error: no overload matches 'Array(String)#<<' with type (String | Nil)
。
在进行类型检查后,如何向current_todos
添加可nillable字符串?
编辑:这里是完整的代码:
require "option_parser"
current_todos = [
"Laundry",
"Walk dog",
"Sing in shower"
]
new_task = nil
OptionParser.parse do |parser|
parser.banner = "Welcome to my todo app!"
parser.on "-a TASK", "--add TASK", "Type a new task" do |task|
new_task = task
end
parser.on "-h", "--help" do
puts parser
exit
end
end
current_todos << new_task if typeof(new_task) == String
current_todos.each do |todo|
puts todo
end
如果new_task
的类型为String|Nil
,则可以测试它是否为非零。然后编译器就会知道它是一个字符串。这里应该有效:
current_todos << new_task if new_task
编译器将理解的另一种更接近原始代码的方法是使用is_a?
:
current_todos << new_task if new_task.is_a?(String)
typeof(var)
给出的是编译时类型,而不是运行时的类型。例如:
def check_type(var : String?)
puts typeof(var)
puts var.class
puts var.is_a? String
puts var.is_a? Nil
puts var.nil?
end
check_type(gets)
如果您输入,它将打印:
(String | Nil)
String
true
false
false
如果您没有输入(gets
返回nil
(,则它将打印:
(String | Nil)
Nil
false
true
true
看起来像current_todos << new_task if new_task.is_a?(String)
这样的东西不起作用的原因是new_task
的新赋值发生在解析器的.on
函数中。由于编译器不知道何时/是否调用它,因为它在闭包中,所以它求助于nil
。
为了迫使它工作,我需要使用.not_nil!