假设你在Ruby中做到这一点:

ar = [1, 2]
x, y = ar

然后,X == 1和y == 2是否有一个方法我可以在自己的类定义将产生同样的效果? e.g。

rb = AllYourCode.new
x, y = rb

到目前为止,我已经能够用这样的赋值操作是使X == RB和y =零。 Python有一个特征是这样的:

>>> class Foo:
...     def __iter__(self):
...             return iter([1,2])
...
>>> x, y = Foo()
>>> x
1
>>> y
2
有帮助吗?

解决方案

是的。定义#to_ary。这将让你的对象可作为用于分配的阵列处理。

irb> o = Object.new
=> #<Object:0x3556ec>
irb> def o.to_ary
       [1, 2]
     end
=> nil
irb> x, y = o
=> [1,2]
irb> x
#=> 1
irb> y
#=> 2

#to_a之间#to_ary的区别在于#to_a用于尝试转换 一个给定的对象阵列,而#to_ary可用如果我们可以把给定的对象为一个数组。这是一个微妙的差异。

其他提示

几乎:

class AllYourCode
   def to_a
     [1,2]
   end
end

rb = AllYourCode.new
x, y = *rb
p x
p y

啪将尝试调用to_ary,然后尝试调用to_a。我不知道你为什么要做到这一点,虽然,这是一个真正的语法功能,恰巧使用Array在执行,而不是Array的功能。

在换句话说,用例多重分配是一样的东西:

# swap
x, y = y, x

# multiple return values
quot, rem = a.divmod(b)

# etc.
name, age = "Person", 100

在换句话说,大部分的对象从(所述Array)被分配的时刻甚至没有明显。

可以不重新定义分配,因为它是一个运算符代替的方法。但是,如果你AllYourCode类是从Array继承,你的例子会工作。

当红宝石遇到分配,它看起来在右侧,并且如果存在一个以上的右值,它收集它们到一个数组。然后,它着眼于左侧。如果有一个左值那里,它被分配的阵列。

def foo 
  return "a", "b", "c" # three rvalues
end

x = foo # => x == ["a", "b", "c"]

如果有多于一个的左值(更具体地,如果它认为逗号),它依次分配右值和丢弃多余的。

x, y, z = foo # => x == "a", y == "b", z == "c"
x, y = foo    # => x == "a", y == "b"
x, = foo      # => x == "a"

您可以做平行分配如果返回一个数组,也因为你已经发现了。

def bar
  ["a", "b", "c"]
end

x = bar       # => x == ["a", "b", "c"]
x, y, z = bar # => x == "a", y == "b", z == "c"
x, y = bar    # => x == "a", y == "b"
x, = bar      # => x == "a"

因此,在你例如,如果RB为数组或从Array,x和y继承将被分配其第一2个值。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top