我是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
最后一宗案件发生了什么?它是否表现为迭代器?任何人都可以举例说明如何使用它吗? 为什么它对第二和第三种情况没有影响?
答案 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中的快捷方式puts
。 puts
采用可变数量的参数,你可以给它多少你想要的。它将全部输出,由换行符分隔。如果你给它一个数组参数,它仍然会输出由换行符分隔的数组中的每个元素。
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 arr
和puts *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)的东西,分配给尾部。"