Orc*_*ris 3 ruby parameters arguments function
例如,如果我有
def function(arg)
#do stuff
end
Run Code Online (Sandbox Code Playgroud)
我怎么只允许arg成为一个数组?我可以
def function(arg)
if arg.class != 'Array'
return 'Error'
else
#do stuff
end
end
Run Code Online (Sandbox Code Playgroud)
但有没有更好的方法呢?
你不能def function(Array arg)用其他语言做 ,但你可以用一个替换你的第二个片段的四行:
def function(arg)
raise TypeError unless arg.is_a? Array
# code...
end
Run Code Online (Sandbox Code Playgroud)
其他人已经指出如何在技术上强制执行某种类型的论点,但您正在与 ruby 思维方式进行根本性的斗争。谷歌搜索“鸭子打字”。
在 ruby 世界中,我们通常不担心参数的类型,而是它是否满足我们想要用它做的接口。换句话说,它像鸭子一样嘎嘎叫吗?够好了!
让我们假设您正在尝试使用 Array 来做某事:
def function(arg)
arg.each do |a|
puts a
end
end
Run Code Online (Sandbox Code Playgroud)
如果你这样称呼它:function(1),你会得到NoMethodError: undefined method 'each'
让我们使用您将其强制为数组的想法。
def function(arg)
raise TypeError unless arg.is_a? Array
arg.each do |a|
puts a
end
end
Run Code Online (Sandbox Code Playgroud)
好的,现在我们犯了一个不同的错误,但是如果使用数组以外的其他东西调用该方法,它仍然会生成错误。
另外,这个怎么办?
function("Hello World".chars)
Run Code Online (Sandbox Code Playgroud)
哎呀,我们有一个错误,尽管该功能本来可以工作!
红宝石方式更像是:
def function(arg)
if arg.respond_to? :each
arg.each do |a|
puts a
end
else
puts arg
end
end
Run Code Online (Sandbox Code Playgroud)
现在您的函数适用于各种输入:
function([1,2,3,4])
function("foo")
function("foo".chars)
Run Code Online (Sandbox Code Playgroud)
至于函数的正确性,您将使用测试进行介绍,而不是编译器。但那完全是另一回事。:)