2311 Stimmen

Wie man eine switch-Anweisung in Ruby schreibt

Wie schreibe ich eine switch Anweisung in Ruby?

2971voto

Chuck Punkte 228137

Ruby verwendet die 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 === Betreiber. Zum Beispiel, 1..5 === x und nicht x === 1..5 .

Dies ermöglicht eine anspruchsvolle when Klauseln (siehe oben). Es kann nicht nur auf Gleichheit, sondern auch auf Bereiche, Klassen und alles Mögliche getestet werden.

Anders als switch Anweisungen in vielen anderen Sprachen, ist Ruby's case hat nicht durchfallen so dass es nicht notwendig ist, die einzelnen when avec un break . Sie können auch mehrere Übereinstimmungen in einer einzigen when Klausel wie when "foo", "bar" .

20 Stimmen

Sie können auch Regex auf das übergebene Argument anwenden: wenn /thisisregex/ nächste Zeile puts "Dies ist die gefundene Übereinstimmung Nr. 1 #{$1}" end

12 Stimmen

Sie können Ihren Code auch kürzen, indem Sie die when y return Anweisung in der gleichen Zeile: when "foo" then "bar"

21 Stimmen

Das ist wichtig: Anders als switch Anweisungen in vielen anderen Sprachen, ist Ruby's case hat NICHT durchfallen so dass es nicht notwendig ist, die einzelnen when con un break .

499voto

kikito Punkte 49986

case...when verhält sich beim Umgang mit Klassen ein wenig unerwartet. Dies ist auf die Tatsache zurückzuführen, dass es die === Betreiber.

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

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

Das bedeutet, dass Sie, wenn Sie eine 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 or number')
end

Gibt aus: "Es ist weder eine Zeichenkette noch eine Zahl".

Glücklicherweise lässt sich dieses Problem leicht lösen. Die === Operator wurde so definiert, dass er Folgendes zurückgibt 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 durch Entfernen der .class von case obj.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

Ich bin heute bei der Suche nach einer Antwort auf dieses Problem gestoßen, und dies war die erste Seite, die erschien, so dass ich dachte, es wäre nützlich für andere in meiner gleichen Situation.

0 Stimmen

Obj='hallo';case obj; when 'hallo' then puts "Es ist hallo" end

0 Stimmen

Mit dem .class Teil in ist interessant, danke. Natürlich ist dies ein völlig angemessenes Verhalten (obwohl ich verstehen könnte, dass es ein weit verbreiteter Irrtum sein könnte, zu denken, dass die It is a string )... Sie testen die Klasse eines beliebigen Objekts, nicht das Objekt selbst. Also, zum Beispiel case 'hello'.class when String then "String!" when Class then "Class!" else "Something else" end führt zu: "Class!" Dies gilt auch für 1.class , {}.class , usw. Ablegen .class erhalten wir "String!" o "Something else" für diese verschiedenen Werte.

1 Stimmen

Danke dafür! Das ist eleganter als meine Lösung, die darin bestand, "case obj.class.to_s" zu verwenden.

253voto

nonopolarity Punkte 138211

Dies geschieht durch case in Ruby. Siehe auch " Anweisung wechseln " 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 weiteres 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

Etwa auf Seite 123 von Die Ruby-Programmiersprache (1. Auflage, O'Reilly) auf meinem Kindle, heißt es, dass die then Schlüsselwort 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 , aber diese Syntax ist in Ruby 1.9 nicht mehr erlaubt).

48 Stimmen

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

2 Stimmen

Dies ist die Antwort, die ich verwendet habe, weil ich eine Variable auf der Grundlage der Ergebnisse einer Fallumschaltung definiere. Anstatt zu sagen type = #{score} jede Zeile, kann ich einfach kopieren, was Sie getan haben. Viel eleganter Ich mag auch die Einzeiler viel besser (wenn möglich)

1 Stimmen

Ich liebe Ruby so sehr dafür, dass ich einfach eine Switch-Anweisung auf eine Variable wie die, weniger Unordnung und kommt direkt auf den Punkt :D setzen kann

120voto

mmdemirbas Punkte 8840

Fall...wenn

Um weitere Beispiele zu nennen 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 den Hinweis " Wie man eine switch-Anweisung in Ruby schreibt ", vor dem Kikito warnt.

0 Stimmen

Danke, das war hilfreich, um mehrere Optionen in einer Zeile zu haben. Ich hatte versucht, Folgendes zu verwenden or

84voto

Robert Kajic Punkte 8134

Viele Programmiersprachen, insbesondere die von C abgeleiteten, unterstützen die sogenannte Schalter Durchfall . Ich habe nach dem besten Weg gesucht, dasselbe in Ruby zu tun, und dachte, es könnte für andere nützlich sein:

In C-ähnlichen Sprachen sieht Fallthrough typischerweise wie folgt 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 das Gleiche 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, die 'a' einen Codeblock auszuführen, bevor er zu 'b' o 'c' aber größtenteils finde ich sie ähnlich genug, um auf dieselbe Weise nützlich zu sein.

0 Stimmen

Fallthrough ist eher ein Problem als eine Eigenschaft. Wenn Ruby die Nachahmung des Fallthroughs unterstützen würde, wäre es leicht zu lösen, indem man die gleiche Bedingung auf mehreren when Zeilen und führt diesen Block aus, wenn die Bedingung erfüllt ist. Aber das wird nicht unterstützt.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X