如何在Ruby中为splat参数设置默认值

jor*_*npg 11 ruby splat

为splat参数设置默认值会产生错误:

1.9.3-p374 :001 > def a b, *c = nil
1.9.3-p374 :002?>   end
SyntaxError: (irb):1: syntax error, unexpected '=', expecting ';' or '\n'
def a b, *c = nil
             ^
    from /Users/me/.rvm/rubies/ruby-1.9.3-p374/bin/irb:16:in `<main>'
Run Code Online (Sandbox Code Playgroud)

我试过的一些变化也不起作用:

1.9.3-p374 :003 > def a b, *c = []
1.9.3-p374 :005 > def a b, (*c) = nil
1.9.3-p374 :007 > def a b, (*c = [])
1.9.3-p374 :009 > def a b, (*c = [1,2,3])
1.9.3-p374 :011 > def a b, *c = [1,2,3]
Run Code Online (Sandbox Code Playgroud)

我在这里看不到不确定性问题,所以看起来应该是可能的.

相关: 为什么非显式splat参数加上默认参数是Ruby 1.9中方法定义的错误语法?

vla*_*its 6

您的尝试使用是违反splat使用的惯例.假设Splats(至少在Ruby中)占用所有额外的(0,1或更多)值.

如果您知道您希望方法参数列表中的第二个值具有默认值,则可以将其从splat中取出并在splat之前使用默认值列出它,如下所示:

def a b, c=nil, *d 
  # rest of code omitted
end
Run Code Online (Sandbox Code Playgroud)

编辑: 回答你的问题,为什么它不能完全清楚.这是语言设计师的设计决定.Matz从未打算让splat运算符使用默认值.这对我来说似乎很合理,因为它旨在用于捕获不确定数量的变量,因为我描述的方法比你描述的可能性读得更清楚,因为你的例子解决的所有问题都可以通过其他方式解决.


Tho*_*emm 5

您可以在方法本身中设置默认值,因为知道默认 splat 返回一个空数组。

def test(a, *b)
  b = "default b" if b == [] # edited as per Tin Man's recommendation
  puts [a, b].inspect
end

test("Test", 1, 2)
# => ["Test", [1, 2]]
test("Test")
# => ["Test", "default b"]
Run Code Online (Sandbox Code Playgroud)

在 Rails 中,您可以检查是否b.present?为空数组被视为空白。希望有帮助。

  • 这是一个可读性和可维护性问题。使用布尔值来连接条件测试和赋值在很大程度上是一种 C/Perl 构造;它很简洁,几乎是神秘的,但没有获得明显的速度(如果有的话)。当用 C 或 Perl 编写时,人们期望能够这样编写,几乎是大男子主义,但 Ruby 的方式是为了提高可读性而更加简洁。另外,如果您使用“and”,然后添加其他测试或作业,优先顺序可能会困扰您,这可能很难追踪。使用“&amp;&amp;”很多时候可以避免优先级问题,但不会增加可读性。 (4认同)