gpt4 book ai didi

ruby - 为什么 ruby​​ 只允许默认参数和 splats 的某些顺序?

转载 作者:数据小太阳 更新时间:2023-10-29 07:53:13 25 4
gpt4 key购买 nike

我在编写 ruby​​ 代码时遇到了一个奇怪的情况:

def foo(bar=true,baz,*args)
end

引发此错误:

syntax error, unexpected tSTAR

而这些:

def foo(bar,baz=true,*args)
end

def foo(bar=true,baz=true,*args)
end

没问题。

更奇怪的是,这些:

def foo(bar,baz=true)
end

def foo(bar=true,baz)
end

两者都有效。

但是,这:

def foo(bar=true,baz,args=true)
end

引发错误,但是这些:

def foo(bar=true,baz=true,args)
end

def foo(bar,baz=true,args=true)
end

很好。

我想有一个合乎逻辑的原因可以解释为什么允许某些组合而不允许其他组合,但我无法在任何地方找到它们,无论是通过谷歌还是搜索 stackoverflow。我的问题很简单:为什么允许其中一些组合,而另一些则不允许?

最佳答案

现有的 Ruby 书籍详细解释​​了这一点。但即使没有,您也会习惯它的逻辑。一个体面的编码器定义的函数首先是强制性的有序参数,如下所示:

def foo( a, b, c=0, d=0 )
# ...
end

简单地说,前 2 个参数转到 ab,最多 2 个可选参数转到 cd,按此顺序。但是你被授予了超越普通礼仪的自由:

def foo( a=0, b )
# ...
end

如果您提供 1 个参数,它将转到 b。如果您提供 2 个参数,它们将按顺序分配给 ab。这是不太体面的,因为它需要向用户学习更多。如果您自己是用户,那您就是对自己不雅,但是,根本没有句法歧义。现在看看这个:

def foo( a=0, b, c=0 )
# ...
end

如果你调用 foo( 1, 2 ),你的意思是 a = 1, b = 2, c = 0,或者 a = 0b = 1c = 2?也许第一个更有可能,但编码规则是,不要猜测用户的意图。因此,Ruby 团队可能决定不宠爱这种语法。您仍然可以通过定义来实现它:

def foo( *args )
a, b, c = case args.size
when 1 then [0, args[0], 0]
when 2 then [*args, 0]
when 3 then args
else fail ArgumentError; "#{args.size} arguments for 1..3!" end
# ...
end

因此,事实上,您被授予了绝对的自由,但 Ruby 会引导您进行良好的实践:让好的代码看起来比糟糕的代码更好。这同样适用于使用 * splat 收集参数。体面的情况是明确的:

def foo( a, b=0, *c )
# ...
end

但是有:

def foo( a=0, b, *c )
# ...
end

当您调用 foo( 1, 2, 3 ) 时,您的意思是 a = 1b = 2c = [3],或 a = 0b = 1c = [2, 3] ?因此,同样,不鼓励第二种情况,但仍然可以实现:

def foo( *c )
a, b = case c.size
when 0 then fail ArgumentError, "Too few arguments!"
when 1 then [0, c.shift]
else [c.shift, c.shift] end
# ...
end

编写带有许多参数的函数,尤其是带有许多有序参数的函数,是一种不好的做法。有一句老话,二元法优于三元法,一元法优于二元法,最后,一元法优于一元法。如果您的方法需要很多参数,您应该通过 replacing it with an object 重构它.这是否回答了您的问题?

关于ruby - 为什么 ruby​​ 只允许默认参数和 splats 的某些顺序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17005707/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com