Computer >> คอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Ruby

คำชี้แจงกรณีทับทิม - เทคนิคขั้นสูง

ไม่มีอะไรจะง่ายและน่าเบื่อไปกว่าคำชี้แจงของคดี มันเป็นสิ่งที่เหลือจาก C คุณใช้มันเพื่อแทนที่ ifs จำนวนมาก ปิดคดี. หรือว่า?

อันที่จริง คำชี้แจงของกรณีใน Ruby นั้นสมบูรณ์และซับซ้อนกว่าที่คุณคิดมาก มาดูตัวอย่างกัน:

case "Hi there"
when String
  puts "case statements match class"
end

# outputs: "case statements match class"

ตัวอย่างนี้แสดงให้เห็นว่าคำสั่ง case ไม่เพียงแค่จับคู่ value ของรายการ แต่ยังเป็นคลาส . เป็นไปได้เพราะว่าภายใต้ประทุน Ruby ใช้ === โอเปอเรเตอร์ หรือที่รู้จักว่า ตัวดำเนินการเท่ากับสามตัว

การแนะนำอย่างรวดเร็วของ === โอเปอเรเตอร์

เมื่อคุณเขียน x === y y ใน Ruby คุณกำลังถามว่า "y อยู่ในกลุ่มที่แสดงโดย x หรือไม่" นี่เป็นคำสั่งทั่วไปมาก ข้อมูลเฉพาะแตกต่างกันไปขึ้นอยู่กับประเภทของกลุ่มที่คุณทำงานด้วย

# Here, the Class.===(item) method is called, which returns true if item is an instance of the class 

String === "hello" # true
String === 1 # false


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

ตอนนี้เรารู้เรื่องนี้แล้ว เราก็สามารถทำอุบายได้ทุกประเภท

ช่วงการจับคู่ในกรณีคำสั่ง

คุณสามารถใช้ ranges ในกรณีของคำสั่ง case ได้ด้วยความจริงที่ว่า range === n เพียงแค่คืนค่า range.include?(n) . ฉันจะมั่นใจได้อย่างไร? อยู่ในเอกสาร

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

# outputs "case statements match inclusion in a range"

จับคู่นิพจน์ทั่วไปกับคำสั่ง case

การใช้ regexes ในคำสั่ง case ก็เป็นไปได้เช่นกัน เพราะ /regexp/ === "string" คืนค่า true เฉพาะเมื่อสตริงตรงกับนิพจน์ทั่วไป เอกสารสำหรับ Regexp อธิบายสิ่งนี้

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

# outputs "they can match regular expressions!"

จับคู่ procs และ lambdas

นี่เป็นเรื่องแปลก เมื่อคุณใช้   Proc#===(item) ก็เหมือนกับการทำ Proc#call(item) . นี่คือเอกสารสำหรับเรื่องนี้ สิ่งนี้หมายความว่าคุณสามารถใช้ lambdas และ procs ในคำสั่ง case ของคุณเป็นตัวจับคู่แบบไดนามิกได้

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

# outputs "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