' *'的行为Ruby中的Array中的运算符

时间:2015-02-23 14:04:47

标签: ruby

我是Ruby的新手。请解释*运算符在这种情况下的工作原理。

arr = [1,2,3]
p arr
arr = *[1,2,3]
p arr
*arr = [1,2,3]
p arr
arr = [1,2,3]
p *arr

输出

[1,2,3]

[1,2,3]

[1,2,3]

1

2

3

最后一宗案件发生了什么?它是否表现为迭代器?任何人都可以举例说明如何使用它吗? 为什么它对第二和第三种情况没有影响?

2 个答案:

答案 0 :(得分:0)

该上下文中数组的“*”运算符将数组转换为参数列表。

假设您有一个带三个参数的方法:

def takes_three(one, two, three)
  puts "first: #{one}, second: #{two}, third: #{three}"
end

如果您尝试这样做:

arr = ["a", "b", "c"]
takes_three(arr)
# => ArgumentError: wrong number of arguments (1 for 3)

你的方法有三个参数,但你只传递了一个 - 那个是一个数组。

如果你想将三个元素的数组转换成方法的三个独立参数,那就是*在这里做的事情:

takes_three(*arr)
# => puts "first: a, second: b, third: c"

您的示例中有什么令人困惑的信念,不管您信不信,您使用p,使用irb中的快捷方式putsputs采用可变数量的参数,你可以给它多少你想要的。它将全部输出,由换行符分隔。如果你给它一个数组参数,它仍然会输出由换行符分隔的数组中的每个元素。

irb(main):068:0> puts ["a", "b", "c"]
a
b
c
irb(main):069:0> puts "a", "b", "c"
a
b
c
irb(main):070:0> puts arr
a
b
c
irb(main):071:0> puts *arr
a
b
c

由于puts "a", "b", "c"puts ["a", "b", "c"]执行相同的操作,puts arrputs *arr也会做同样的事情。由于puts *arr等同于puts 1, 2, 3,因此它将数组扩展为该方法的单独参数。

因此,您尝试使用puts进行调查会让人感到困惑,因为puts采用可变数量的参数,并且对一个n元素数组的参数执行相同的操作,就像使用n分别对每个元素进行论证。大多数方法都不会那样工作,因此对于大多数方法*,改变你给方法的参数的性质,也会改变方法的作用。它对于一种间接是很有用的,在这种间接中,您可以动态地构建要在数组中传递的参数,而不是在源代码中编写它们。

答案 1 :(得分:0)

这是 splat运算符(*)。它可以用于在方法调用中扩展数组到参数列表,或者在一些赋值中扩展到“全部”。以下是一些例子:

1)使用传递数组将方法调用作为参数列表

考虑以下方法:

def my_method(argument1, argument2, argument3)
end

您可以使用*(或splat)运算符将数组转换为参数列表:

arguments = [1, 2, 3]
my_method(*arguments)

https://ruby-doc.org/core-2.2.0/doc/syntax/calling_methods_rdoc.html

2)使用分配到'采取所有'

*,有时称为" splat运算符,"用数组做了很多事情。如果它位于赋值运算符(=)的左侧,就像在您的示例中一样,它只意味着"将所有内容留下。"

示例:

a = [1, 2, 3, 4, 5]
head, *tail = a
p head #=> 1
p tail #=> [2, 3, 4, 5]

如果您省略了该代码中的splat,它将改为:

head, tail = [1, 2, 3, 4, 5]
p head # => 1
p tail # => 2

但是当你将splat添加到尾部时,它意味着"所有没有被分配给前一个变量(head)的东西,分配给尾部。"

<强>源: What does this mean in Ruby language?