điểm trở lại trong Ruby là gì?


79

Sự khác biệt giữa returnvà chỉ đặt một biến như sau:

không trở lại

def write_code(number_of_errors)
  if number_of_errors > 1
     mood = "Ask me later"
  else
     mood = "No Problem"
  end  
  mood
end

trở về

def write_code(number_of_errors)
  if number_of_errors > 1
    mood =  "Ask me later"
  else
    mood = puts "No Problem"
  end  
  return mood
end

Câu trả lời:


118

return cho phép bạn bứt phá sớm:

def write_code(number_of_errors)
  return "No problem" if number_of_errors == 0
  badness = compute_badness(number_of_errors)
  "WHAT?!  Badness = #{badness}."
end

Nếu number_of_errors == 0, sau đó "No problem"sẽ được trả lại ngay lập tức. Tuy nhiên, ở phần cuối của một phương pháp, nó không cần thiết, như bạn đã quan sát.


Chỉnh sửa: Để chứng minh rằng returnthoát ngay lập tức, hãy xem xét chức năng này:

def last_name(name)
  return nil unless name
  name.split(/\s+/)[-1]
end

Nếu bạn gọi hàm này là last_name("Antal S-Z"), nó sẽ trả về "S-Z". Nếu bạn gọi nó là last_name(nil), nó sẽ trả về nil. Nếu return không hủy bỏ ngay lập tức, nó sẽ cố gắng thực thi nil.split(/\s+/)[-1], điều này sẽ gây ra lỗi.


ok, ví dụ tốt. vì vậy return lưu trữ giá trị trả về nhưng để phần còn lại của phương thức thực thi. Không thể chờ đợi để sử dụng nó.
thenengah

4
Không, ngược lại: return ngay lập tức thoát khỏi phương thức. Nếu bạn nghĩ về ví dụ đó, sẽ không hữu ích khi tính toán mức độ tệ hại nếu bạn biết mọi thứ đều ổn. Tôi sẽ chỉnh sửa câu trả lời của mình để làm rõ ràng hơn.
Antal Spector-Zabusky

8
Bạn có thể sử dụng return, breakv.v. mà không cần tham số - chúng sẽ trả về niltheo mặc định.
Nakilon

38

Việc sử dụng "return" là không cần thiết nếu nó là dòng cuối cùng được thực thi trong phương thức, vì Ruby tự động trả về biểu thức được đánh giá cuối cùng.

Bạn thậm chí không cần "tâm trạng" cuối cùng đó, cũng không cần những nhiệm vụ đó trong câu lệnh IF.

def write_code(number_of_errors)
    if number_of_errors > 1
       "ERROR"
    else
       "No Problem"
    end  
end

puts write_code(10)

Đầu ra:

LỖI


37
Đến từ nền tảng không phải Ruby, đầu ra đó chắc chắn là WTF. :)
Patrick

return có thể thoát khỏi quá trình thực hiện sớm.
Joe.wang

1
Return cũng có thể hữu ích khi có phương thức trả về nil thay vì giá trị của biểu thức được đánh giá cuối cùng, vì vậy đôi khi bạn sẽ thấy trả về không có đối số ở cuối phương thức.
garythegoat

1
@garythegoat: hoặc bạn có thể viết đơn giản nil.
Karoly Horvath

4

Tôi sử dụng return khi xem qua một danh sách và tôi muốn thoát khỏi chức năng nếu bất kỳ thành viên nào trong danh sách đáp ứng tiêu chí. Tôi có thể thực hiện điều này chỉ với một câu lệnh như:

list.select{|k| k.meets_criteria}.length == 0

trong một số tình huống, nhưng

list.each{|k| return false if k.meets_criteria}

cũng là một dòng - với tâm trí của tôi, một số tính linh hoạt được bổ sung. Ví dụ, ví dụ đầu tiên giả định rằng đây là dòng duy nhất trong phương thức và chúng tôi muốn quay lại từ thời điểm này bất kể điều gì. Nhưng nếu đây là một thử nghiệm để xem liệu có an toàn khi tiếp tục với phần còn lại của phương pháp hay không, thì ví dụ đầu tiên sẽ cần xử lý điều đó theo một cách khác.

BIÊN TẬP:

Để thêm một số tính linh hoạt, hãy xem xét dòng mã sau:

list_of_method_names_as_symbols.each{|k| list_of_objects.each{|j| return k if j.send(k)}}

Tôi chắc chắn rằng điều này có thể được thực hiện, trong một dòng, mà không cần return, nhưng tôi không biết làm thế nào.

Nhưng đây là một dòng mã khá linh hoạt có thể được gọi với bất kỳ danh sách các phương thức boolean và danh sách các đối tượng thực thi các phương thức đó.

BIÊN TẬP

Cần lưu ý rằng tôi đang giả sử dòng này nằm bên trong một phương thức, không phải một khối.


Nhưng đây chủ yếu là một sự lựa chọn theo phong cách, tôi nghĩ rằng trong hầu hết các tình huống, bạn có thể và có thể nên tránh sử dụng return.


breakthậm chí còn hữu ích hơn trong những trường hợp này.
Nakilon

4

Ruby trở lại luôn luôn! cách tốt nhất là

def write_code(number_of_errors)
  (number_of_errors > 1)? "ERROR" : "No Problem"
end

có nghĩa là nếu number_of_errors> 1, nó sẽ trả về LỖI khác Không có vấn đề gì


3

Ruby tốt đẹp của nó cung cấp cho tính năng tốt này là không chỉ định câu lệnh trả về một cách rõ ràng nhưng tôi chỉ cảm thấy, như một tiêu chuẩn lập trình, người ta nên luôn cố gắng chỉ định câu lệnh "return" bất cứ khi nào cần thiết. Điều này giúp làm cho mã dễ đọc hơn đối với những người đến từ các nền tảng khác nhau như C ++, Java, PHP, v.v. và đang học ruby. câu lệnh "return" sẽ không gây hại gì, vậy tại sao lại bỏ qua cách trả về thông thường và chuẩn hơn từ các hàm.


4
"vậy tại sao lại bỏ qua cách trả về thông thường và tiêu chuẩn hơn từ các hàm" ← bởi vì trong Ruby , bỏ qua return tiêu chuẩn thông thường. Nếu bạn nhìn thấy một returnmã Ruby có kiểu dáng đẹp, nó phải có lý do, chẳng hạn như thoát ra sớm . Việc cố gắng áp dụng các quy ước về kiểu mã từ ngôn ngữ này sang ngôn ngữ khác chỉ khiến việc tham gia các lập trình viên có kinh nghiệm và giữ cho kiểu mã của bạn nhất quán trở nên khó khăn hơn.
David Moles

tôi vẫn bắt bản thân mình đặt dấu chấm phẩy vào cuối dòng
gdbj

Đó chẳng phải là số 2 trong Zen of Ruby, "ngầm vẫn tốt hơn là rõ ràng"? ;-)
Đánh dấu

1

Một lưu ý nhỏ cho những người đến từ các ngôn ngữ khác. Giả sử bạn có một chức năng như OP và bạn sử dụng quy tắc "điều cuối cùng được tính" để đặt giá trị trả về của mình một cách tự động:

def write_code(number_of_errors)
  if number_of_errors > 1
     mood = "Ask me later"
  else
     mood = "No Problem"
  end  
end

và giả sử bạn thêm câu lệnh gỡ lỗi (hoặc ghi nhật ký):

def write_code(number_of_errors)
  if number_of_errors > 1
     mood = "Ask me later"
  else
     mood = "No Problem"
  end  
  puts "### mood = #{mood}"
end

Bây giờ hãy đoán xem. Bạn đã làm hỏng mã của mình, vì giá trị putstrả về nil, bây giờ trở thành giá trị trả về từ hàm.

Giải pháp là tập thói quen luôn đặt giá trị trả về một cách rõ ràng ở dòng cuối cùng, theo cách OP đã làm:

def write_code(number_of_errors)
  if number_of_errors > 1
     mood = "Ask me later"
  else
     mood = "No Problem"
  end  
  puts "### mood = #{mood}"
  mood
end

-1

Sự không cần thiết returnở dòng cuối cùng trong hàm chỉ là đường cú pháp của Ruby. Trong hầu hết các ngôn ngữ thủ tục, bạn cần viết returntrong mỗi hàm (không có giá trị trong C ++).


3
Tôi sẽ không gọi nó là một đường cú pháp ... đặc điểm cốt lõi ở đây là gần như mọi thứ đều là một biểu thức . ifcâu lệnh, khối câu lệnh. Đó là những gì cho phép sự thể hiện này.
Karoly Horvath

Tôi đồng ý với Karoly - nó không phải là đường cú pháp vì mọi thứ đều là một biểu thức.
fatuhoku
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.