ruby中的运算符*和(*)是什么意思?

Aru*_*hit 13 ruby ruby-1.9.3

我刚才向Ruby splat oprator介绍了自己.而且我玩的很多.但是下面的实验让我想起了两次:)

langs = ["java", "csharp", "ruby", "haskell" ]
# => ["java", "csharp", "ruby", "haskell"]

 l1,*,l2 = *langs
# => ["java", "csharp", "ruby", "haskell"]
 l1
# => "java"
 l2
# => "haskell"

 l1,*,*,l2 = *langs
SyntaxError: (irb):27: syntax error, unexpected tSTAR
l1,*,*,l2 = *langs
      ^
    from /usr/bin/irb:12:in `<main>'
Run Code Online (Sandbox Code Playgroud)

是的,错误很明显,因为我*(splat)在同一个参数列表中使用了多个1个运算符.

现在我试着玩它.

l1,(*),(*),l2 = *langs
# => ["java", "csharp", "ruby", "haskell"]
Run Code Online (Sandbox Code Playgroud)

啊!这里有效.但不明白为什么会这样呢?

 l1
# => "java"
 l2
# => "haskell"
 l1,(*),l2 = *langs
# => ["java", "csharp", "ruby", "haskell"]
 l1
# => "java"
 l2
# => "ruby"
Run Code Online (Sandbox Code Playgroud)

从上面的例子看,它似乎正在跳过数组元素.

问题是:

  • (a)调用运算符(*)是什么?

  • (b)当我在行中使用splat(*)时,l1,*,l2 = *langs它会消耗所有元素 - "csharp", "ruby".有什么方法可以看到*技术上消耗的东西吗?显然,如果l1,*,l2 = *langs不是,我正在使用它l1,l*,l2 = *langs.

Pin*_*nyM 9

这是由于Matz解释了括号如何与并行赋值一起工作.

例如:

a, b, c = *[1, 2, 3]
a => 1
b => 2
c => 3
Run Code Online (Sandbox Code Playgroud)

不同于:

a, (b, c) = *[1, 2, 3]
a => 1
b => 2
c => nil
Run Code Online (Sandbox Code Playgroud)

基本上,括号表示:将此索引处的右手元素分配给parens中的变量.因此分配给2 b,索引处没有任何内容1可以分配给c.类似地,(*)将仅获取给定索引处的元素并分发它.

# the * is interpreted to mean 'take all remaining elements'
a, * = 1, 2, 3, 4

# the * is interpreted to mean 'take all remaining elements except
# the last element'
a, *, c = 1, 2, 3, 4

# incorrect syntax, can't splat more than once on all remaining
# elements
a, *, *, c = 1, 2, 3, 4

# the * is interpreted to mean 'take all elements at index 1'
a, (*), c = 1, 2, 3, 4

# the *'s are interpreted to mean 'take all elements at index 1,
# then again at index 2'
a, (*), (*), c = 1, 2, 3, 4
Run Code Online (Sandbox Code Playgroud)

通常,*运算符与变量一起使用*foo- 但如果不是,它将保持其位置并将元素赋值视为变量(实际上是丢弃它们)

  • splat运算符在有或没有括号的情况下是相同的.()告诉ruby从右侧挑出一个元素并将其分配给括号内容.当*在没有变量的赋值的左侧使用时,它只是一个占位符,用于将赋值转移到后续元素,而不实际将"splatted"元素赋值给变量.所以,不,你不能告诉事实是什么被分配给`*`或`(*)`因为你不是在任何地方坚持它,而是用它作为占位符. (2认同)

nzi*_*nab 6

可以这样想:括号(忽略变量名或splat运算符)从数组中访问单个元素:

l1,  (), (), l2 = *['a', 'b', 'c', 'd']
 ^   ^   ^   ^
'a' 'b' 'c' 'd'
Run Code Online (Sandbox Code Playgroud)

如果它是一个数组数组,使用括号更有意义:

>> l1,(l3, l4),(l5, l6),l2 = *['a', ['b', 'c'], ['d', 'e'], 'f']
=> ["a", ["b", "c"], ["d", "e"], "f"]
>> l1
=> "a"
>> l3
=> "b"
>> l4
=> "c"
>> l5
=> "d"
>> l6
=> "e"
>> l2
=> "f"
Run Code Online (Sandbox Code Playgroud)

因此,(*)从数组中获取单个元素,并进行splat分配.括号本身采用SINGLE元素,然后splat接受单个元素并"splats"它.

值得注意的是,从阵列执行多变量赋值时,阵列侧不需要splat:

>> a,b,c = ['a', 'b', 'c']
=> ["a", "b", "c"]
>> a
=> "a"
>> b
=> "b"
>> c
=> "c"
Run Code Online (Sandbox Code Playgroud)


Pat*_*ity 6

(*)真的只是从右侧读取一个元素.考虑这个例子,它在langs数组中有第五个元素:

langs = ["java", "csharp", "ruby", "haskell", "python" ]
Run Code Online (Sandbox Code Playgroud)

所以当你使用普通的splat时,你会得到:

l1,*,l2 = langs

l1 #=> "java"
l2 #=> "python"
Run Code Online (Sandbox Code Playgroud)

与括号中的示例相反:

l1,(*),(*),l2 = langs

l1 #=> "java"
l2 #=> "haskell"
Run Code Online (Sandbox Code Playgroud)

我想提一下,在这种情况下,您通常_会将中间值分配给"nothing"(相当于最后一个示例):

l1,_,_,l2 = langs

l1 #=> "java"
l2 #=> "haskell"
Run Code Online (Sandbox Code Playgroud)

如果要查看最终位于中间值内的内容,可以将值显式分配给变量,如下所示:

l1,*m,l2 = *langs

l1 #=> "java"
l2 #=> "python"
m  #=> ["csharp","ruby","haskell"]
Run Code Online (Sandbox Code Playgroud)

或者与另一个例子:

l1,(*m1),(*m2),l2 = langs

l1 #=> "java"
l2 #=> "haskell"
m1 #=> ["csharp"]
m2 #=> ["ruby"]
Run Code Online (Sandbox Code Playgroud)

所以我希望这清楚地表明它(*)不是一个独立的运算符,但实际上只是括号内的一个splat,因此没有自己的名字.