Frage Wie schreibe ich eine switch-Anweisung in Ruby?


Wie schreibe ich eine Switch-Anweisung in Ruby?


1829
2018-06-04 01:18


Ursprung


Antworten:


Ruby verwendet das case Ausdruck stattdessen.

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 vergleicht das Objekt in der when Klausel mit dem Objekt in der case Klausel unter Verwendung der === Operator. Beispielsweise, 1..5 === x, und nicht x === 1..5.

Dies ermöglicht anspruchsvoll when Klauseln wie oben gesehen. Bereiche, Klassen und alle möglichen Dinge können getestet werden und nicht nur die Gleichheit.

nicht wie switch Aussagen in vielen anderen Sprachen, Ruby's case hat nicht durchfallenEs ist also nicht nötig, jeden zu beenden when mit einem break. Sie können auch mehrere Treffer in einem einzigen angeben when Klausel wie when "foo", "bar".


2303
2018-06-04 01:22



case...when verhält sich beim Umgang mit Klassen etwas unerwartet. Dies ist aufgrund der Tatsache, dass es die verwendet === Operator.

Dieser Operator funktioniert wie erwartet mit Literalen, aber nicht mit Klassen:

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

Dies bedeutet, dass wenn Sie a case ... when über die Klasse eines Objekts wird dies nicht funktionieren:

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')
end

Wird gedruckt "Es ist keine Zeichenfolge".

Zum Glück ist das leicht zu lösen. Das === Operator wurde so definiert, dass er zurückkehrt true Wenn Sie es mit einer Klasse verwenden und eine Instanz dieser Klasse als zweiten Operanden angeben:

Fixnum === 1 # => true

Kurz gesagt, der obige Code kann behoben werden, indem Sie die .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')
end

Ich habe dieses Problem heute bei der Suche nach einer Antwort gefunden, und dies war die erste erscheinende Seite, also dachte ich mir, dass sie für andere in meiner Situation nützlich wäre.


396
2018-04-17 15:20



Es ist erledigt von Fall in Rubin. Siehe auch Dieser Artikel auf Wikipedia.

Zitiert:

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

Ein anderes Beispiel:

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

Um Seite 123 (Ich benutze Kindle) von Der Ruby-Programmier-Lanugage (1. Ausgabe, O'Reilly), heißt es then Stichwort nach dem when Klauseln können durch einen Zeilenumbruch oder ein Semikolon ersetzt werden (genau wie in der if then else Syntax). (Ruby 1.8 erlaubt auch einen Doppelpunkt anstelle von then... Diese Syntax ist in Ruby 1.9 nicht mehr erlaubt.)


187
2018-06-04 01:20



    Fall ... wann

Um weitere Beispiele hinzuzufügen Chucks Antwort:

Mit Parameter:

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

Ohne Parameter:

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

Bitte beachten Sie Das Thema dieser Kikito warnt.


88
2017-07-05 13:19



Viele Programmiersprachen, insbesondere solche, die von C abgeleitet sind, haben Unterstützung für das sogenannte Fallout deaktivieren. Ich war auf der Suche nach dem besten Weg, das gleiche in Ruby zu tun und dachte, dass es für andere nützlich sein könnte:

In C-ähnlichen Sprachen sieht der Fallout typischerweise so aus:

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;
}

In Ruby kann dasselbe auf folgende Weise erreicht werden:

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

Dies ist nicht unbedingt gleichwertig, denn es ist nicht möglich zu lassen 'a' Führen Sie einen Codeblock aus, bevor Sie durchgehen 'b' oder 'c', aber ich finde es meistens ähnlich genug, um auf die gleiche Weise nützlich zu sein.


64
2017-12-07 12:11



In Ruby 2.0 können Sie auch lambdas in verwenden case Aussagen wie folgt:

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

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

Sie können auch Ihre eigenen Vergleicher einfach mit einem Struct mit einer benutzerdefinierten erstellen ===

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

(Beispiel aus "Können Procs mit Case-Anweisungen in Ruby 2.0 verwendet werden?".)

Oder mit einer kompletten Klasse:

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

(Beispiel aus "Wie funktioniert eine Ruby Case-Anweisung und was können Sie damit tun?".)


63
2017-08-01 00:04



Sie können reguläre Ausdrücke verwenden, um z. B. einen Zeichenfolgetyp zu finden:

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

Rubine case wird den Gleichheitsoperanden verwenden === dafür (danke @ JimDeville). Weitere Informationen finden Sie unter "Ruby Operatoren"Dies kann auch mit @mmdemirbas Beispiel (ohne Parameter) erfolgen, nur dieser Ansatz ist für diese Arten von Fällen sauberer.


47
2017-10-16 12:17



Wenn Sie wissen möchten, wie Sie eine OR-Bedingung in einem Ruby-Switch-Fall verwenden:

Also, in einem case Aussage, a , ist das Äquivalent von || in einem (n if Erklärung.

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

Viele andere Dinge, die Sie mit einer Ruby-Case-Anweisung tun können


29
2017-07-03 06:46



Es heißt case und es funktioniert wie man es erwarten würde, plus viel mehr Spaß Sachen mit freundlicher Genehmigung von === welche die Tests implementiert.

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

Jetzt für etwas Spaß:

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

Und es stellt sich heraus, dass Sie auch eine beliebige if / else-Kette ersetzen können (das heißt, auch wenn die Tests keine gemeinsame Variable beinhalten) mit case indem man die Initiale weglässt case Parameter und nur Ausdrücke schreiben, wo die erste Übereinstimmung ist, was Sie wollen.

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

24
2018-02-05 20:40