Trả về hai và nhiều giá trị từ một phương thức


105

Có khả năng trả về nhiều giá trị từ phương thức không? Một cái gì đó như thế này:

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

[a, b, c] = someMethod

Câu trả lời:


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

Bạn nên sử dụng định dạng mã, không phải định dạng văn bản. Thụt lề dòng bốn dấu cách và sự kỳ lạ do >>lời nhắc của irb sẽ biến mất.
Chris Lutz

4
Kể từ khi một sự trở lại rõ ràng được coi là không thành ngữ Ruby, bạn cũng có thể sử dụng một sự trở lại tuyệt đối bằng cách đặt một cách rõ ràng các giá trị trở lại trong một danh sách:def foo_and_bar; ['foo', 'bar']; end
Dennis

43

Ruby có một dạng ràng buộc hủy cấu trúc hạn chế:

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

Nó cũng có một dạng cấu trúc ràng buộc hạn chế:

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

Bạn có thể kết hợp hai hình thức đó như sau:

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

Có một số điều khác bạn có thể làm với liên kết hủy cấu trúc / cấu trúc. Tôi đã không hiển thị bằng cách sử dụng toán tử splat ( *) ở phía bên phải. Tôi đã không hiển thị lồng (sử dụng parantheses). Tôi không cho thấy rằng bạn có thể sử dụng liên kết hủy cấu trúc trong danh sách tham số của một khối hoặc phương thức.

Đây chỉ là một món khai vị:

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

Trong khi trả về nhiều giá trị thường hữu ích, tôi thường thấy nó là một con trỏ đến một yêu cầu đối tượng mới.

Đó là, tôi thường thấy rằng những giá trị trả về đó được gắn chặt với nhau theo ý nghĩa / ngữ cảnh và được chuyển xung quanh như vậy. Vì vậy, trong những trường hợp này, tôi sẽ tạo một đối tượng mới để buộc chúng lại với nhau. Đó là một mùi mã đặc biệt mà tôi đã học được để nhận ra.


4
nhiều tự do hơn, nhiều trách nhiệm hơn. Người chuyên về ruby ​​có kinh nghiệm sẽ tận dụng nó và viết một số mã đẹp. trong khi những tân binh bằng ruby ​​có thể khiến mọi thứ trở nên tồi tệ hơn.
Fengd

1
Rõ ràng là không phải lúc nào cũng vậy, nếu không những thứ tương tự chunksẽ không tồn tại. Nguyên tắc tuyệt vời mặc dù. Đúng là mùi mã. Đá lên.
Darth Egrerious

6

Bạn cũng có thể đạt được điều này trả về một mảng, như

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

có vẻ chức năng tương đương với

def sumdiff(x, y)
    return x+y, x-y
end
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.