不,Ruby 实际上不支持返回两个对象。 (顺便说一句:你返回的是对象,而不是变量。更准确地说,你返回的是指向对象的指针。)
但是,它确实支持并行分配。如果您在作业的右侧有多个对象,则这些对象将被收集到 Array:
foo = 1, 2, 3
# is the same as
foo = [1, 2, 3]
如果在赋值左侧有多个“目标”(变量或 setter 方法),则变量将绑定到右侧 Array 的元素:
a, b, c = ary
# is the same as
a = ary[0]
b = ary[1]
c = ary[2]
如果右侧不是Array,它将使用to_ary 方法转换为一个
a, b, c = not_an_ary
# is the same as
ary = not_an_ary.to_ary
a = ary[0]
b = ary[1]
c = ary[2]
如果我们把两者放在一起,我们就得到了
a, b, c = d, e, f
# is the same as
ary = [d, e, f]
a = ary[0]
b = ary[1]
c = ary[2]
与此相关的是赋值左侧的 splat 运算符。它的意思是“取所有右边Array的剩余元素”:
a, b, *c = ary
# is the same as
a = ary[0]
b = ary[1]
c = ary.drop(2) # i.e. the rest of the Array
最后但同样重要的是,并行赋值可以使用括号嵌套:
a, (b, c), d = ary
# is the same as
a = ary[0]
b, c = ary[1]
d = ary[2]
# which is the same as
a = ary[0]
b = ary[1][0]
c = ary[1][1]
d = ary[2]
当你 return 来自方法或 next 或 break 来自块时,Ruby 会将这种类型视为赋值的右侧,所以
return 1, 2
next 1, 2
break 1, 2
# is the same as
return [1, 2]
next [1, 2]
break [1, 2]
顺便说一句,这也适用于方法和块的参数列表(方法更严格,块不那么严格):
def foo(a, (b, c), d) p a, b, c, d end
bar {|a, (b, c), d| p a, b, c, d }
例如,“不那么严格”的块是 Hash#each 工作的原因。它实际上yields 一个单个两个元素Array 的键和值到块,但我们通常写
some_hash.each {|k, v| }
而不是
some_hash.each {|(k, v)| }