Ruby并行分配

jsv*_*isa 5 ruby

我想测试并行赋值的返回值,我写puts (x, y = 1, 2),但它不起作用,并打印错误消息:

SyntaxError: (irb):74: syntax error, unexpected ',', expecting ')'
puts (x,y =1,2)
    ^
(irb):74: syntax error, unexpected ')', expecting end-of-input
Run Code Online (Sandbox Code Playgroud)

有什么不对的吗?

Mar*_*eed 12

你有两个问题.

  1. puts和之间的空格(可防止括号列表被解释为参数列表.在方法名称后放置空格后,任何参数列表都必须在括号之外,并且任何带括号的部分必须是合法表达式.在Ruby中,(x,y,z)不是合法的单个表达式,因此您得到上述错误.

    如果你删除空格,你得到这个:

    > puts(x, y = 1, 2)    
    NameError: undefined local variable or method `x' for main:Object
    
    Run Code Online (Sandbox Code Playgroud)

    那是因为你的第二个问题:

  2. 该语句puts(x,y = 1,2)被解析为puts(x, y=1, 2); 也就是说,Ruby将其解释为传递三个参数puts: x第一个y=1是第二个,2第三个是第三个.由于x它不在作业的左侧并且尚未定义,因此您会收到上述错误.

    使用一组额外的括号将整个赋值组合为一个参数:

    > puts((x,y=1,2))    
    1    
    2    
    
    Run Code Online (Sandbox Code Playgroud)

但请注意,这是传递包含两个项目的单个列表.它没有区别puts,但它将用于区分列表和单个参数的方法:

> def foo(a,b) puts "a=#{a},b=#{b}" end
> foo((x,y=1,2))
ArgumentError: wrong number of arguments (1 for 2)
Run Code Online (Sandbox Code Playgroud)

所以在这种情况下你需要一个标点符号 - splat运算符:

> foo(*(x,y=1,2))   
a=1, b=2
Run Code Online (Sandbox Code Playgroud)

有趣但没有实际意义的事实是,一旦你将括号加倍,你可以根据需要放回空间:

> puts ((x, y = 1, 2))    
1    
2    
Run Code Online (Sandbox Code Playgroud)

但是,再一次,它将它们从参数包装器转变为一个额外的表达式包装器; 你可以在不改变任何东西的情况下放置任意数量的括号.这意味着在这种foo情况下,splat运算符必须超出两组括号:

> foo (*(x,y=1,2))
SyntaxError: (irb):24: syntax error, unexpected tSTAR
> foo *((x,y=1,2))
a=1, b=2
Run Code Online (Sandbox Code Playgroud)

然而,当第一个参数本身包含括号时,使用无括号形式的Ruby通常被认为是不好的风格.根据你的Ruby版本,你也许会得到一个这样的言论的​​警告,但是即使你不这样做,最好是使用完全括号的版本(与方法名称后没有空格).


cra*_*ind 5

这应该工作

puts( (x, y = 1, 2) )
Run Code Online (Sandbox Code Playgroud)