ส่งคืนค่าสองค่าขึ้นไปจากวิธีการ


105

มีความเป็นไปได้ที่จะคืนค่าหลายค่าจากวิธีการหรือไม่? สิ่งนี้:

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

[a, b, c] = someMethod

คำตอบ:


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 จะหายไป
Chris Lutz

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 ( *) ทางด้านขวามือ ฉันไม่ได้แสดงการทำรัง (โดยใช้ parantheses) ฉันไม่ได้แสดงให้เห็นว่าคุณสามารถใช้การผูกแบบทำลายโครงสร้างในรายการพารามิเตอร์ของบล็อกหรือวิธีการ

นี่เป็นเพียงอาหารเรียกน้ำย่อย:

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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.