从方法返回两个或更多值


105

是否有可能从方法中返回多个值?像这样:

def someMethod()
  return ["a", 10, SomeObject.new]
end

[a, b, c] = someMethod

Answers:


160
def sumdiff(x, y)
  return x+y, x-y
end
#=> nil

sumdiff(3, 4)
#=> [7, -1]

a = sumdiff(3,4)
#=> [7, -1]
a
#=> [7, -1]

a,b=sumdiff(3,4)
#=> [7, -1]
a
#=> 7
b
#=> -1

a,b,c=sumdiff(3,4)
#=> [7, -1]
a
#=> 7
b
#=> -1
c
#=> nil

您应该使用代码格式,而不是文本格式。缩进四个空格,irb >>提示引起的怪异现象将消失。
克里斯·卢兹

4
由于显式返回被认为是非惯用的Ruby,因此您还可以通过将返回值显式放入列表中来使用隐式返回:def foo_and_bar; ['foo', 'bar']; end
Dennis

43

Ruby具有有限形式的解构绑定:

ary = [1, 2, 3, 4]
a, b, c = ary
p a # => 1
p b # => 2
p c # => 3

a, b, *c = ary
p c # => [3, 4]

a, b, c, d, e = ary
p d # => 4
p e # => nil

它还具有结构绑定的有限形式:

 a = 1, 2, 3
 p a # => [1, 2, 3]

您可以像下面这样组合这两种形式:

a, b = b, a # Nice way to swap two variables

a, b = 1, 2, 3
p b # => 2

def foo; return 1, 2 end
a, b = foo
p a # => 1
p b # => 2

解构/结构化绑定还可以做其他几件事。我没有显示使用splat运算符(*在右侧)。我没有显示嵌套(使用括号)。我没有显示您可以在块或方法的参数列表中使用解构绑定。

这只是一个开胃菜:

def foo(((a, b, c, d), e, *f), g, *h)
  local_variables.sort.each do |lvar| puts "#{lvar} => #{eval(lvar).inspect}" end
end

foo([[1, 2, 3], 4, 5, 6], 7, 8, 9)
# a => 1
# b => 2
# c => 3
# d => nil
# e => 4
# f => [5, 6]
# g => 7
# h => [8, 9]

16

虽然返回多个值通常很有用,但我通常发现它是一个指向新对象需求的指针。

也就是说,我通常会发现这些返回值在含义/上下文中紧密联系在一起,并因此被传递。因此,在这些情况下,我将创建一个新对象将它们绑定在一起。这是我已经学会识别的特殊代码气味。


4
更多自由,更多责任。有经验的红宝石主义者会利用它并编写一些漂亮的代码。红宝石菜鸟会使情况变得更糟。
fengd

1
很显然,并非总是如此,否则chunk就不会存在类似的事情。优秀的原则。确实有代码气味。继续前进。
Darth Egregious

6

您也可以实现返回数组的方法,例如

def sumdiff(x, y)
    [x+y, x-y]
end

在功能上似乎等同于

def sumdiff(x, y)
    return x+y, x-y
end
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.