วิธีการเขียนคำสั่ง switch ใน Ruby


คำตอบ:


2669

Ruby ใช้caseนิพจน์แทน

case x
when 1..5
  "It's between 1 and 5"
when 6
  "It's 6"
when "foo", "bar"
  "It's either foo or bar"
when String
  "You passed a string"
else
  "You gave me #{x} -- I have no idea what to do with that."
end

Ruby เปรียบเทียบวัตถุในส่วนwhenคำสั่งกับวัตถุในส่วนcaseคำสั่งที่ใช้ตัว===ดำเนินการ ยกตัวอย่างเช่นและไม่1..5 === xx === 1..5

สิ่งนี้จะช่วยให้whenคำสั่งที่ซับซ้อนดังที่เห็นด้านบน ช่วงชั้นเรียนและทุกสิ่งสามารถทดสอบได้มากกว่าความเท่าเทียมกัน

ซึ่งแตกต่างจากswitchงบในภาษาอื่น ๆ อีกมากมายทับทิมcaseไม่มีฤดูใบไม้ร่วงผ่านจึงไม่มีความจำเป็นที่จะจบแต่ละกับwhen breakนอกจากนี้คุณยังสามารถระบุตรงกันหลายอย่างในตัวเดียวประโยคเช่นwhenwhen "foo", "bar"


12
นอกจากนี้คุณยังสามารถทำ regex ในอาร์กิวเมนต์ผ่าน: เมื่อ / thisisregex / บรรทัดถัดไป ทำให้ "นี่คือการแข่งขันที่พบ nr. 1 # {$ 1}" จบ
Automatico

8
นอกจากนี้ยังเป็นที่น่าสังเกตว่าคุณสามารถย่อรหัสของคุณโดยใส่whenและreturnคำสั่งในบรรทัดเดียวกัน:when "foo" then "bar"
Alexander - Reinstate Monica

9
สำคัญ:แตกต่างจากswitchงบในภาษาอื่น ๆ อีกมากมายทับทิมcaseไม่ได้มีฤดูใบไม้ร่วงผ่านจึงไม่มีความจำเป็นที่จะจบแต่ละกับwhen break
janniks

3
thenจำนวนมากดังนั้นคะแนนเสียงยังไม่ได้เอ่ยถึงคำหลัก โปรดดูคำตอบอื่น ๆ
Clint Pachl

442

case...whenมีพฤติกรรมเล็กน้อยโดยไม่คาดคิดเมื่อจัดการคลาส นี่คือสาเหตุที่ใช้ตัว===ดำเนินการ

ตัวดำเนินการนั้นทำงานได้ตามที่คาดหวังโดยใช้ตัวอักษร แต่ไม่ใช่กับคลาส:

1 === 1           # => true
Fixnum === Fixnum # => false

ซึ่งหมายความว่าหากคุณต้องการทำcase ... whenคลาสของวัตถุสิ่งนี้จะไม่ทำงาน:

obj = 'hello'
case obj.class
when String
  print('It is a string')
when Fixnum
  print('It is a number')
else
  print('It is not a string or number')
end

จะพิมพ์ "ไม่ใช่สตริงหรือตัวเลข"

โชคดีที่มันสามารถแก้ไขได้อย่างง่ายดาย ===ผู้ประกอบการที่ได้รับการกำหนดไว้เพื่อให้มันกลับtrueถ้าคุณใช้มันกับการเรียนและจัดหาตัวอย่างของการเรียนที่เป็นตัวถูกดำเนินการที่สอง:

Fixnum === 1 # => true

ในระยะสั้นรหัสข้างต้นสามารถแก้ไขได้โดยการลบ.class:

obj = 'hello'
case obj  # was case obj.class
when String
  print('It is a string')
when Fixnum
  print('It is a number')
else
  print('It is not a string or number')
end

ฉันเจอปัญหานี้วันนี้ในขณะที่มองหาคำตอบและนี่เป็นหน้าแรกที่ปรากฏดังนั้นฉันคิดว่ามันจะเป็นประโยชน์กับผู้อื่นในสถานการณ์เดียวกันของฉัน


obj = 'hello'; case obj; เมื่อ 'สวัสดี' จบจากนั้น "สวัสดี" จบลง
Sugumar Venkatesan

การมี.classส่วนร่วมเป็นสิ่งที่น่าสนใจที่จะต้องทราบขอบคุณ แน่นอนว่านี่เป็นพฤติกรรมที่เหมาะสมอย่างสมบูรณ์ (แม้ว่าฉันจะเห็นว่ามันอาจเป็นความผิดพลาดทั่วไปที่คิดว่าจะพิมพ์ออกมาIt is a string) ... คุณกำลังทดสอบคลาสของวัตถุที่กำหนดเองบางอย่างไม่ใช่วัตถุเอง ดังนั้นสำหรับตัวอย่างเช่น: case 'hello'.class when String then "String!" when Class then "Class!" else "Something else" endผลลัพธ์ใน: "Class!"นี้ทำงานเหมือนกันสำหรับ1.class, {}.classฯลฯ หยด.classที่เราได้รับ"String!"หรือ"Something else"ค่าต่างๆเหล่านี้
lindes

219

มันทำโดยใช้caseใน Ruby โปรดดูที่ " คำสั่งสลับ " ในวิกิพีเดีย

ที่ยกมา:

case n
when 0
  puts 'You typed zero'
when 1, 9
  puts 'n is a perfect square'
when 2
  puts 'n is a prime number'
  puts 'n is an even number'
when 3, 5, 7
  puts 'n is a prime number'
when 4, 6, 8
  puts 'n is an even number'
else
  puts 'Only single-digit numbers are allowed'
end

ตัวอย่างอื่น:

score = 70

result = case score
   when 0..40 then "Fail"
   when 41..60 then "Pass"
   when 61..70 then "Pass with Merit"
   when 71..100 then "Pass with Distinction"
   else "Invalid Score"
end

puts result

ในหน้า 123 ของภาษาการเขียนโปรแกรม Ruby (รุ่นที่ 1, O'Reilly) บน Kindle ของฉันกล่าวว่าthenคำหลักที่ตามหลังwhenคำสั่งสามารถถูกแทนที่ด้วยบรรทัดใหม่หรือเซมิโคลอน (เหมือนในif then elseไวยากรณ์) (Ruby 1.8 ยังอนุญาตให้ใช้โคลอนแทนได้thenแต่ไม่อนุญาตให้ใช้ไวยากรณ์นี้ใน Ruby 1.9 อีกต่อไป)


38
when (-1.0/0.0)..-1 then "Epic fail"
Andrew Grimm

นี่คือคำตอบที่ฉันใช้เพราะฉันกำหนดตัวแปรตามผลลัพธ์ของการสลับเคส แทนที่จะพูดtype = #{score}แต่ละบรรทัดฉันสามารถคัดลอกสิ่งที่คุณทำ มากสง่างามมากขึ้นฉันยังเหมือนหนึ่งสมุทรที่ดีมาก (ถ้าเป็นไปได้)
onebree

ฉันรู้ว่านี่ไม่เกี่ยวข้องกับสาระสำคัญของคำตอบ แต่ 4 ก็เป็นสี่เหลี่ยมจัตุรัสที่สมบูรณ์แบบเช่นกัน
Nick Moore

109

กรณีเมื่อ ...

หากต้องการเพิ่มตัวอย่างเพิ่มเติมในคำตอบของ Chuck :

ด้วยพารามิเตอร์:

case a
when 1
  puts "Single value"
when 2, 3
  puts "One of comma-separated values"
when 4..6
  puts "One of 4, 5, 6"
when 7...9
  puts "One of 7, 8, but not 9"
else
  puts "Any other thing"
end

ไม่มีพารามิเตอร์:

case
when b < 3
  puts "Little than 3"
when b == 3
  puts "Equal to 3"
when (1..10) === b
  puts "Something in closed range of [1..10]"
end

โปรดระวัง " วิธีการเขียนคำสั่ง switch ใน Ruby " ที่ kikito เตือน


ขอบคุณสิ่งนี้มีประโยชน์สำหรับการมีหลายตัวเลือกในหนึ่งบรรทัด ฉันพยายามใช้or
sixty4bit

73

การเขียนโปรแกรมภาษาหลายคนโดยเฉพาะอย่างยิ่งที่ได้มาจาก C, มีการสนับสนุนที่เรียกว่าสวิทช์ Fallthrough ฉันกำลังค้นหาวิธีที่ดีที่สุดในการทำเช่นเดียวกันใน Ruby และคิดว่าอาจเป็นประโยชน์ต่อผู้อื่น:

ในภาษา C-like fallthrough มักมีลักษณะดังนี้:

switch (expression) {
    case 'a':
    case 'b':
    case 'c':
        // Do something for a, b or c
        break;
    case 'd':
    case 'e':
        // Do something else for d or e
        break;
}

ใน Ruby สามารถทำได้ในวิธีต่อไปนี้:

case expression
when 'a', 'b', 'c'
  # Do something for a, b or c
when 'd', 'e'
  # Do something else for d or e
end

สิ่งนี้ไม่เทียบเท่าอย่างเคร่งครัดเพราะมันเป็นไปไม่ได้ที่จะให้เอ็กซี'a'คิ้วท์โค้ดก่อนที่จะผ่านไป'b'หรือ'c'แต่สำหรับส่วนใหญ่ฉันพบว่ามันคล้ายกันมากพอที่จะเป็นประโยชน์ในทางเดียวกัน


72

ใน Ruby 2.0 คุณสามารถใช้ lambdas ในcaseข้อความสั่งได้ดังนี้:

is_even = ->(x) { x % 2 == 0 }

case number
when 0 then puts 'zero'
when is_even then puts 'even'
else puts 'odd'
end

คุณยังสามารถสร้างเครื่องมือเปรียบเทียบของคุณเองได้อย่างง่ายดายโดยใช้โครงสร้างด้วยแบบกำหนดเอง ===

Moddable = Struct.new(:n) do
  def ===(numeric)
    numeric % n == 0
  end
end

mod4 = Moddable.new(4)
mod3 = Moddable.new(3)

case number
when mod4 then puts 'multiple of 4'
when mod3 then puts 'multiple of 3'
end

(ตัวอย่างที่นำมาจาก " สามารถใช้ procs กับคำสั่ง case ใน Ruby 2.0 ได้หรือไม่ ")

หรือด้วยคลาสที่สมบูรณ์:

class Vehicle
  def ===(another_vehicle)
    self.number_of_wheels == another_vehicle.number_of_wheels
  end
end

four_wheeler = Vehicle.new 4
two_wheeler = Vehicle.new 2

case vehicle
when two_wheeler
  puts 'two wheeler'
when four_wheeler
  puts 'four wheeler'
end

(ตัวอย่างที่นำมาจาก " คำชี้แจงกรณีทับทิมทำงานอย่างไรและคุณสามารถทำอะไรกับมันได้ ")


52

คุณสามารถใช้นิพจน์ทั่วไปเช่นการค้นหาประเภทของสตริง:

case foo
when /^(true|false)$/
   puts "Given string is boolean"
when /^[0-9]+$/ 
   puts "Given string is integer"
when /^[0-9\.]+$/
   puts "Given string is float"
else
   puts "Given string is probably string"
end

Ruby caseจะใช้ตัวถูกดำเนินการที่เท่าเทียมกัน===สำหรับสิ่งนี้ (ขอบคุณ @JimDeville) ข้อมูลเพิ่มเติมสามารถดูได้ที่ " Ruby Operators " สิ่งนี้สามารถทำได้โดยใช้ตัวอย่าง @mmdemirbas (โดยไม่มีพารามิเตอร์) วิธีนี้จะสะอาดกว่าสำหรับเคสประเภทนี้


34

หากคุณอยากรู้วิธีใช้เงื่อนไข OR ในกรณีสวิตช์ Ruby:

ดังนั้นในcaseคำสั่ง a ,จะเทียบเท่ากับ||ในifคำสั่ง

case car
   when 'Maruti', 'Hyundai'
      # Code here
end

ดูที่ " คำชี้แจงกรณีทับทิมทำงานอย่างไรและคุณสามารถทำอะไรกับมันได้ "


รหัสการจัดรูปแบบที่ไม่ได้ทำงานในบทความที่เชื่อมโยง :-)
froderik

33

มันถูกเรียกcaseและใช้งานได้ตามที่คุณคาดหวังรวมไปถึงความสนุกที่เพิ่มเติมจาก===การทดสอบ

case 5
  when 5
    puts 'yes'
  else
    puts 'else'
end

ตอนนี้เพื่อความสนุก:

case 5 # every selector below would fire (if first)
  when 3..7    # OK, this is nice
  when 3,4,5,6 # also nice
  when Fixnum  # or
  when Integer # or
  when Numeric # or
  when Comparable # (?!) or
  when Object  # (duhh) or
  when Kernel  # (?!) or
  when BasicObject # (enough already)
    ...
end

และมันกลับกลายเป็นว่าคุณสามารถแทนที่ข้อใดข้อหนึ่ง / เชน (นั่นคือแม้ว่าการทดสอบจะไม่เกี่ยวข้องกับตัวแปรทั่วไป) ด้วยการcaseปล่อยcaseพารามิเตอร์เริ่มต้นและเพียงแค่เขียนนิพจน์ที่การแข่งขันครั้งแรกเป็นสิ่งที่คุณต้องการ

case
  when x.nil?
    ...
  when (x.match /'^fn'/)
    ...
  when (x.include? 'substring')
    ...
  when x.gsub('o', 'z') == 'fnzrq'
    ...
  when Time.now.tuesday?
    ...
end

23

Ruby ใช้caseสำหรับการเขียนคำสั่ง switch

ตามcaseเอกสาร:

คำสั่ง Case ประกอบด้วยเงื่อนไขที่เป็นทางเลือกซึ่งอยู่ในตำแหน่งที่สามารถโต้แย้งได้caseและเป็นศูนย์หรือwhenอนุประโยคขึ้นไป whenประโยคแรกเพื่อให้ตรงกับเงื่อนไข (หรือเพื่อประเมินความจริงบูลีนหากเงื่อนไขเป็นโมฆะ) "ชนะ" และรหัสของมันจะถูกดำเนินการ ค่าของข้อความสั่ง case คือค่าของwhenclause ที่สำเร็จหรือnilหากไม่มี clause ดังกล่าว

คำสั่ง case สามารถลงท้ายด้วยelseclause แต่ละwhenคำสั่งสามารถมีค่าตัวเลือกหลายค่าคั่นด้วยเครื่องหมายจุลภาค

ตัวอย่าง:

case x
when 1,2,3
  puts "1, 2, or 3"
when 10
  puts "10"
else
  puts "Some other number"
end

รุ่นที่สั้นกว่า:

case x
when 1,2,3 then puts "1, 2, or 3"
when 10 then puts "10"
else puts "Some other number"
end

และในฐานะที่เป็น " คำสั่งกรณีรูบี - เทคนิคขั้นสูง " อธิบายทับทิมcase;

สามารถใช้กับช่วง :

case 5
when (1..10)
  puts "case statements match inclusion in a range"
end

## => "case statements match inclusion in a range"

สามารถใช้กับRegex :

case "FOOBAR"
when /BAR$/
  puts "they can match regular expressions!"
end

## => "they can match regular expressions!"

สามารถใช้กับProcs และ Lambdas :

case 40
when -> (n) { n.to_s == "40" }
  puts "lambdas!"
end

## => "lambdas"

นอกจากนี้ยังสามารถใช้กับคลาสการแข่งขันของคุณเอง:

class Success
  def self.===(item)
    item.status >= 200 && item.status < 300
  end
end

class Empty
  def self.===(item)
    item.response_size == 0
  end
end

case http_response
when Empty
  puts "response was empty"
when Success
  puts "response was a success"
end

22

คุณอาจต้องการใช้แฮชของวิธีการทั้งนี้ขึ้นอยู่กับกรณีของคุณ

หากมีรายการที่มีความยาวwhenและแต่ละรายการมีค่าที่เป็นรูปธรรมเพื่อเปรียบเทียบกับ (ไม่ใช่ช่วงเวลา) มันจะมีประสิทธิภาพมากกว่าในการประกาศแฮชของวิธีการแล้วเรียกวิธีที่เกี่ยวข้องจากแฮชแบบนั้น

# Define the hash
menu = {a: :menu1, b: :menu2, c: :menu2, d: :menu3}

# Define the methods
def menu1
  puts 'menu 1'
end

def menu2
  puts 'menu 2'
end

def menu3
  puts 'menu3'
end

# Let's say we case by selected_menu = :a
selected_menu = :a

# Then just call the relevant method from the hash
send(menu[selected_menu])

21

เนื่องจากswitch caseส่งคืนวัตถุเดียวเสมอเราสามารถพิมพ์ผลลัพธ์ได้โดยตรง:

puts case a
     when 0
        "It's zero"
     when 1
        "It's one"
     end

20

ค่าหลายกรณีและเมื่อไม่มีค่า:

print "Enter your grade: "
grade = gets.chomp
case grade
when "A", "B"
  puts 'You pretty smart!'
when "C", "D"
  puts 'You pretty dumb!!'
else
  puts "You can't even use a computer!"
end

และวิธีแก้ปัญหาการแสดงออกปกติที่นี่:

print "Enter a string: "
some_string = gets.chomp
case
when some_string.match(/\d/)
  puts 'String has numbers'
when some_string.match(/[a-zA-Z]/)
  puts 'String has letters'
else
  puts 'String has no numbers or letters'
end

2
ทำไมไม่เพียงแค่case some_string, when /\d/, (stuff), when /[a-zA-Z]/, (stuff), end(ขึ้น,บรรทัดใหม่)
Doorknob

2
โอ้และส่วนแรกครอบคลุมในคำตอบนี้แล้วและคำตอบมากมายพูดถึง regex แล้ว ตรงไปตรงคำตอบนี้ไม่เพิ่มอะไรใหม่และฉันกำลังลงคะแนนและโหวตเพื่อลบ
Doorknob

@DoorknobofSnow นี่เป็นการแสดงว่าคุณสามารถใช้โซลูชัน Regex และคั่นด้วยเครื่องหมายจุลภาคในกรณีสวิตช์ ไม่แน่ใจว่าทำไมการแก้ปัญหาทำให้คุณเจ็บปวดมาก
123

ดังนั้นหากพวกเขาได้รับ "F" เกรดที่ถูกต้องความผิดของรหัสของคุณจะหายไปกรณีหรือไม่
Mike Graf

ฉันชอบอารมณ์ขันของเรื่องนี้และความจริงที่ว่ามันแสดงให้เห็นว่าคุณสามารถจับคู่สตริงกับเคสได้
Emery

13

คุณสามารถเขียนcaseนิพจน์ได้สองวิธีใน Ruby:

  1. คล้ายกับชุดifคำสั่ง
  2. ระบุเป้าหมายที่อยู่ถัดจากcaseและแต่ละwhenข้อจะถูกเปรียบเทียบกับเป้าหมาย
age = 20
case 
when age >= 21
puts "display something"
when 1 == 0
puts "omg"
else
puts "default condition"
end

หรือ:

case params[:unknown]
when /Something/ then 'Nothing'
when /Something else/ then 'I dont know'
end

แม้ว่ารหัสของคุณอาจตอบคำถามคุณควรเพิ่มคำอธิบายสั้น ๆ เกี่ยวกับสิ่งที่รหัสของคุณทำและวิธีแก้ปัญหาเริ่มต้น
user1438038

ฉันจะพิจารณาเคล็ดลับนี้ในอนาคต
ysk

10

คุณสามารถทำสิ่งนี้ได้อย่างเป็นธรรมชาติมากขึ้น

case expression
when condtion1
   function
when condition2
   function
else
   function
end

9

มีคำตอบที่ดีมากมาย แต่ฉันคิดว่าฉันจะเพิ่ม factoid หนึ่งอัน .. หากคุณพยายามเปรียบเทียบวัตถุ (คลาส) ให้แน่ใจว่าคุณมีวิธีการจัดส่งในอวกาศ (ไม่ใช่เรื่องตลก) หรือเข้าใจวิธีการเปรียบเทียบ

" Ruby Equality and Object Comparison " เป็นการสนทนาที่ดีในหัวข้อ


7
สำหรับการอ้างอิงวิธี "space-ship" คือ<=>ซึ่งจะใช้ในการส่งกลับ -1, 0, 1 หรือศูนย์ขึ้นอยู่กับว่าการเปรียบเทียบส่งกลับน้อยกว่าเท่ากับเท่ากับมากกว่าหรือไม่เทียบเท่าตามลำดับ เอกสารโมดูลเปรียบเทียบของ Ruby ได้อธิบายไว้แล้ว
ชายดีบุก

7

ตามที่ระบุไว้ในหลายคำตอบข้างต้น===ผู้ประกอบการจะใช้ภายใต้ประทุนบนcase/ whenงบ

นี่คือข้อมูลเพิ่มเติมเกี่ยวกับโอเปอเรเตอร์นั้น:

ผู้ประกอบการความเสมอภาคกรณี: ===

คลาสในตัวรูบี้จำนวนมากเช่น String, Range, และ Regexp นำเสนอการใช้งานของ===โอเปอเรเตอร์ของตัวเองหรือที่เรียกว่า "case-equality", "triple equals" หรือ "threequals" เนื่องจากมันมีการใช้งานที่แตกต่างกันในแต่ละชั้นเรียนมันจะทำงานแตกต่างกันไปขึ้นอยู่กับประเภทของวัตถุที่ถูกเรียกใช้ โดยทั่วไปแล้วจะส่งกลับค่าจริงหากวัตถุทางด้านขวา "เป็นของ" หรือ "เป็นสมาชิกของ" วัตถุทางด้านซ้าย ตัวอย่างเช่นมันสามารถใช้ในการทดสอบว่าวัตถุเป็นตัวอย่างของการเรียน (หรือหนึ่งในชั้นย่อยของมัน)

String === "zen"  # Output: => true
Range === (1..2)   # Output: => true
Array === [1,2,3]   # Output: => true
Integer === 2   # Output: => true

ผลเดียวกันสามารถทำได้ด้วยวิธีการอื่น ๆ ซึ่งอาจมีความเหมาะสมดีที่สุดสำหรับงานเช่นและis_a?instance_of?

การใช้งานช่วงของ ===

เมื่อ===โอเปอเรเตอร์ถูกเรียกบนอ็อบเจกต์ช่วงมันจะคืนค่าจริงหากค่าด้านขวาอยู่ภายในช่วงทางด้านซ้าย

(1..4) === 3  # Output: => true
(1..4) === 2.345 # Output: => true
(1..4) === 6  # Output: => false

("a".."d") === "c" # Output: => true
("a".."d") === "e" # Output: => false

โปรดจำไว้ว่า===โอเปอเรเตอร์จะเรียกใช้===เมธอดของวัตถุด้านซ้าย ดังนั้นจะเทียบเท่ากับ(1..4) === 3 (1..4).=== 3กล่าวอีกนัยหนึ่งคลาสของตัวถูกดำเนินการทางด้านซ้ายจะกำหนด===ว่าจะเรียกใช้งานวิธีการใดดังนั้นตำแหน่งของตัวถูกดำเนินการจึงไม่สามารถใช้แทนกันได้

การดำเนินการ Regexp ของ ===

ผลตอบแทนจริงถ้าสตริงด้านขวาตรงกับการแสดงออกปกติทางด้านซ้าย

/zen/ === "practice zazen today"  # Output: => true
# is similar to
"practice zazen today"=~ /zen/

ความแตกต่างที่เกี่ยวข้องเพียงอย่างเดียวระหว่างสองตัวอย่างข้างต้นคือเมื่อมีการจับคู่===คืนค่าจริงและ=~ส่งกลับจำนวนเต็มซึ่งเป็นค่าจริงในทับทิม เราจะกลับมาที่นี่ในไม่ช้า


5
puts "Recommend me a language to learn?"
input = gets.chomp.downcase.to_s

case input
when 'ruby'
    puts "Learn Ruby"
when 'python'
    puts "Learn Python"
when 'java'
    puts "Learn Java"
when 'php'
    puts "Learn PHP"
else
    "Go to Sleep!"
end

1
ช่วยได้มากขึ้นถ้าคุณให้คำอธิบายว่าทำไมนี่จึงเป็นโซลูชันที่ต้องการและอธิบายวิธีการทำงาน เราต้องการที่จะให้ความรู้ไม่เพียง แต่ให้รหัส
ชายดีบุก


1

ฉันเริ่มใช้:

a = "secondcase"

var_name = case a
  when "firstcase" then "foo"
  when "secondcase" then "bar"
end

puts var_name
>> "bar"

จะช่วยให้รหัสกะทัดรัดในบางกรณี


1
รหัสเช่นนี้มักจะควรจะทำโดยใช้Hashมากกว่าcaseคำสั่ง
ทอมลอร์ด

การใช้แฮชจะเร็วขึ้นเมื่อสวิตช์นั้นใหญ่ขึ้น
มนุษย์ดีบุก

1

ไม่รองรับการแสดงออกปกติในสภาพแวดล้อมของคุณ? เช่นShopify Script Editor (เมษายน, 2018):

[ข้อผิดพลาด]: RegExpคงที่แบบไม่กำหนดค่าเริ่มต้น

วิธีแก้ปัญหาต่อไปนี้เป็นการรวมกันของวิธีการที่กล่าวถึงก่อนหน้านี้แล้วในที่นี้และที่นี่ :

code = '!ADD-SUPER-BONUS!'

class StrContains
  def self.===(item)
    item.include? 'SUPER' or item.include? 'MEGA' or\
    item.include? 'MINI' or item.include? 'UBER'
  end
end

case code.upcase
when '12345PROMO', 'CODE-007', StrContains
  puts "Code #{code} is a discount code!"
when '!ADD-BONUS!'
  puts 'This is a bonus code!'
else
  puts 'Sorry, we can\'t do anything with the code you added...'
end

ผมใช้orในคำสั่งวิธีการเรียนตั้งแต่มีลำดับความสำคัญสูงกว่า|| .include?หากคุณเป็นทับทิม - นาซีโปรดจินตนาการว่าฉันใช้สิ่งนี้(item.include? 'A') || ...แทน ทดสอบrepl.it


1

การเน้นเครื่องหมายจุลภาค ( ,) ในwhenประโยคเป็นสิ่งสำคัญ จะทำหน้าที่เป็น||ของifคำสั่งที่เป็นมันไม่หรือเปรียบเทียบและไม่และเปรียบเทียบระหว่างการแสดงออกที่คั่นของwhenประโยค ดูคำสั่งกรณีต่อไปนี้:

x = 3
case x
  when 3, x < 2 then 'apple'
  when 3, x > 2 then 'orange'
end
 => "apple"

xมีจำนวนไม่น้อยกว่า 2 "apple"แต่ค่าตอบแทนเป็น ทำไม? เนื่องจากxเป็น 3 และตั้งแต่',`` acts as an| | , it did not bother to evaluate the expressionx <2 '

คุณอาจคิดว่าการใช้ANDคุณสามารถทำสิ่งนี้ได้ แต่ไม่ได้ผล:

case x
  when (3 && x < 2) then 'apple'
  when (3 && x > 2) then 'orange'
end
 => nil 

มันใช้งานไม่ได้เพราะ(3 && x > 2)ประเมินเป็นจริงและ Ruby นำค่า True มาเปรียบเทียบxกับ===ซึ่งไม่เป็นความจริงเนื่องจากxเป็น 3

หากต้องการทำการ&&เปรียบเทียบคุณจะต้องปฏิบัติcaseเหมือนif/ elseบล็อก:

case
  when x == 3 && x < 2 then 'apple'
  when x == 3 && x > 2 then 'orange'
end

ในการเขียนโปรแกรมทับทิมหนังสือภาษา, แมทซ์กล่าวว่ารูปแบบหลังนี้เป็นเรื่องง่าย (และไม่บ่อยใช้) รูปแบบซึ่งเป็นอะไรมากไปกว่าไวยากรณ์ทางเลือกสำหรับif/ /elsif elseอย่างไรก็ตามไม่ว่าจะมีการใช้งานไม่บ่อยนักหรือไม่ก็ตามฉันไม่เห็นวิธีอื่นในการแนบหลาย&&นิพจน์สำหรับwhenประโยคที่กำหนด


นี่ดูเหมือนจะไม่ดีสำหรับฉัน การใช้ไวยากรณ์ทางเลือกที่หายากทำให้งงงวยโดยไม่จำเป็น ทำไมไม่ใช้งานปกติif...elsif? ดูเหมือนว่าคุณกำลังพยายามที่จะผสมคำสั่งกรณีและเงื่อนไข ทำไม? เพียงแค่ใส่เงื่อนไขภายในบล็อกเมื่อเช่น when 3; ( x < 2 ) ? 'apple' : 'orange'
sondra.kinsey

0

เราสามารถเขียนคำสั่ง switch สำหรับหลายเงื่อนไขได้

ตัวอย่างเช่น,

x = 22

CASE x
  WHEN 0..14 THEN puts "#{x} is less than 15"    
  WHEN 15 THEN puts "#{x} equals 15" 
  WHEN 15 THEN puts "#{x} equals 15" 
  WHEN 15..20 THEN puts "#{x} is greater than 15" 
  ELSE puts "Not in the range, value #{x} " 
END

1
สิ่งนี้จะไม่ทำงาน คำหลักทับทิม (เช่น. case, when, end) เป็นกรณี ๆ ไปและไม่สามารถเป็นตัวพิมพ์ใหญ่เช่นนี้
sondra.kinsey

NoMethodError (undefined method CASE 'สำหรับ main: Object) ` ดังที่ @ sondra.kinsey พูดว่าคุณไม่สามารถใช้ตัวพิมพ์ใหญ่ได้ ทับทิมจะคิดว่ามันคงที่
Tin Man

0

ตัวcaseดำเนินการคำสั่งนั้นเหมือนswitchในภาษาอื่น ๆ

นี่คือไวยากรณ์ของswitch...caseใน C:

switch (expression)
​{
    case constant1:
      // statements
      break;
    case constant2:
      // statements
      break;
    .
    .
    .
    default:
      // default statements
}

นี่คือไวยากรณ์ของcase...whenใน Ruby:

case expression
  when constant1, constant2 #Each when statement can have multiple candidate values, separated by commas.
     # statements 
     next # is like continue in other languages
  when constant3
     # statements 
     exit # exit is like break in other languages
  .
  .
  .
  else
     # statements
end

ตัวอย่างเช่น:

x = 10
case x
when 1,2,3
  puts "1, 2, or 3"
  exit
when 10
  puts "10" # it will stop here and execute that line
  exit # then it'll exit
else
  puts "Some other number"
end

สำหรับข้อมูลเพิ่มเติมโปรดดูcaseเอกสารประกอบ

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