Bir yöntemden iki veya daha fazla değer döndür


105

Yöntemden birden çok değer döndürme olasılığı var mı? Bunun gibi bir şey:

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

[a, b, c] = someMethod

Yanıtlar:


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

Metin biçimlendirmesini değil kod biçimlendirmesini kullanmalısınız. Satırları dört boşluk girintili yapın ve irb komutunun neden olduğu gariplik ortadan >>kalkacaktır.
Chris Lutz

4
Açık bir dönüş deyimsel olmayan Ruby olarak kabul edildiğinden, dönüş değerlerini bir listeye açıkça koyarak örtük bir dönüş de kullanabilirsiniz:def foo_and_bar; ['foo', 'bar']; end
Dennis

43

Ruby'nin sınırlı bir yıkıcı bağlama biçimi vardır:

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

Ayrıca sınırlı bir yapılandırma bağına sahiptir:

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

Bu iki formu şu şekilde birleştirebilirsiniz:

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

Yıkma / yapılandırma bağlarıyla yapabileceğiniz başka şeyler var. *Sağ tarafta uyarıcı operatörünü ( ) kullanarak göstermedim . İç içe geçmeyi göstermedim (parantez kullanarak). Bir bloğun veya yöntemin parametre listesinde yıkım bağını kullanabileceğinizi göstermedim.

İşte sadece bir meze:

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

Birden çok değer döndürmek genellikle yararlı olsa da, genellikle yeni bir nesne gereksinimi için bir işaretçi buluyorum.

Yani, genellikle bu dönüş değerlerinin anlam / bağlam olarak birbirine sıkı sıkıya bağlı olduğunu ve bu şekilde aktarıldığını görüyorum. Yani bu durumlarda bunları birbirine bağlamak için yeni bir nesne yaratırdım. Tanımayı öğrendiğim özel bir kod kokusu.


4
daha fazla özgürlük, daha fazla sorumluluk. Deneyimli yakut uzmanı bundan faydalanır ve güzel kodlar yazar. Ruby çaylakları işleri daha da kötüleştirebilirken.
fengd

1
Açıkçası bu her zaman böyle chunkdeğildir, yoksa böyle şeyler olmazdı. Yine de mükemmel prensip. Kod kokusu gerçekten. Devam et.
Darth Aleni

6

Bunu bir dizi döndürerek de başarabilirsiniz, örneğin

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

işlevsel olarak eşdeğer görünen

def sumdiff(x, y)
    return x+y, x-y
end
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.