Wie schreibe ich eine switch
Erklärung in Ruby?
Wie schreibe ich eine switch
Erklärung in Ruby?
Antworten:
Ruby verwendet stattdessen den case
Ausdruck .
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 des ===
Operators. Zum Beispiel 1..5 === x
und nicht x === 1..5
.
Dies ermöglicht ausgefeilte when
Klauseln, wie oben gezeigt. Bereiche, Klassen und alle möglichen Dinge können nicht nur auf Gleichheit geprüft werden.
Im Gegensatz zu switch
Aussagen in vielen anderen Sprachen hat Ruby's case
keinen Durchfall , sodass es nicht erforderlich ist, jede when
mit einem zu beenden break
. Sie können auch mehrere Übereinstimmungen in einer einzigen when
Klausel wie angeben when "foo", "bar"
.
when
und return
in dieselbe Zeile setzen:when "foo" then "bar"
then
. Bitte beachten Sie auch die anderen Antworten.
case...when
verhält sich beim Umgang mit Klassen etwas unerwartet. Dies liegt an der Tatsache, dass der ===
Operator verwendet wird.
Dieser Operator arbeitet erwartungsgemäß mit Literalen, jedoch nicht mit Klassen:
1 === 1 # => true
Fixnum === Fixnum # => false
Dies bedeutet, dass case ... when
dies nicht funktioniert , wenn Sie die Klasse eines Objekts überschreiben möchten :
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 "Es ist keine Zeichenfolge oder Zahl" aus.
Glücklicherweise ist dies leicht zu lösen. Der ===
Operator wurde so definiert, dass er zurückgegeben wird, true
wenn Sie ihn 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 Folgendes entfernt wird .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 auf dieses Problem gestoßen, als ich nach einer Antwort gesucht habe, und dies war die erste Seite, die angezeigt wurde. Daher dachte ich, dass dies für andere in derselben Situation nützlich sein würde.
.class
ist interessant festzustellen, dass die Rolle dabei ist, danke. Natürlich ist dies ein völlig angemessenes Verhalten (obwohl ich sehen konnte, dass es ein häufiger Fehler ist, zu glauben, dass es gedruckt wird It is a string
) ... Sie testen die Klasse eines beliebigen Objekts, nicht das Objekt selbst. So zum Beispiel: case 'hello'.class when String then "String!" when Class then "Class!" else "Something else" end
Ergebnisse in: "Class!"
Dies funktioniert auf die gleiche für 1.class
, {}.class
etc. Dropping .class
, wir bekommen "String!"
oder "Something else"
für diese verschiedenen Werte.
Dies geschieht case
in Ruby. Siehe auch " Switch-Anweisung " 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
Auf Seite 123 von The Ruby Programming Language (1. Ausgabe, O'Reilly) auf meinem Kindle heißt es, dass das then
Schlüsselwort nach den when
Klauseln durch eine neue Zeile oder ein Semikolon ersetzt werden kann (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.)
when (-1.0/0.0)..-1 then "Epic fail"
type = #{score}
jede Zeile zu sagen , kann ich einfach kopieren, was Sie getan haben. Viel eleganter mag ich auch die Einzeiler viel besser (wenn möglich)
Um weitere Beispiele zu Chucks Antwort hinzuzufügen :
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 " Wie schreibe ich eine switch-Anweisung in Ruby ", vor dem kikito warnt.
or
Viele Programmiersprachen, insbesondere die von C abgeleiteten, unterstützen den sogenannten Switch Fallthrough . Ich suchte nach dem besten Weg, dies auch in Ruby zu tun, und dachte, es könnte für andere nützlich sein:
In C-ähnlichen Sprachen sieht Fallthrough normalerweise 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, da es nicht möglich ist 'a'
, einen Codeblock ausführen zu lassen , bevor er zu 'b'
oder durchfällt 'c'
, aber zum größten Teil finde ich ihn ähnlich genug, um auf die gleiche Weise nützlich zu sein.
In Ruby 2.0 können Sie Lambdas auch case
wie folgt in Anweisungen verwenden:
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 einfach Ihre eigenen Komparatoren erstellen, indem Sie eine Struktur mit einer benutzerdefinierten Struktur verwenden ===
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 eine Ruby-Fallbeschreibung funktioniert und was Sie damit tun können ".)
Sie können reguläre Ausdrücke verwenden, z. B. das Suchen eines Zeichenfolgentyps:
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
wird dafür den Gleichheitsoperanden verwenden ===
(danke @JimDeville). Weitere Informationen finden Sie unter " Ruby Operators ". Dies kann auch am Beispiel von @mmdemirbas (ohne Parameter) erfolgen. Nur dieser Ansatz ist für diese Art von Fällen sauberer.
Wenn Sie wissen möchten, wie eine ODER-Bedingung in einem Ruby-Switch-Fall verwendet wird:
In einer case
Anweisung ist a ,
also das Äquivalent zu ||
einer if
Anweisung.
case car
when 'Maruti', 'Hyundai'
# Code here
end
Siehe " Wie eine Ruby-Fallerklärung funktioniert und was Sie damit tun können ".
Es heißt case
und es funktioniert wie erwartet, plus viel mehr lustiges Zeug, mit ===
dessen Hilfe die Tests implementiert werden.
case 5
when 5
puts 'yes'
else
puts 'else'
end
Nun zum 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 (dh auch wenn die Tests keine gemeinsame Variable enthalten) case
durch ersetzen können, indem Sie den Anfangsparameter case
weglassen und nur Ausdrücke schreiben, bei denen die erste Übereinstimmung Ihren Wünschen entspricht.
case
when x.nil?
...
when (x.match /'^fn'/)
...
when (x.include? 'substring')
...
when x.gsub('o', 'z') == 'fnzrq'
...
when Time.now.tuesday?
...
end
Ruby verwendet die case
zum Schreiben von switch-Anweisungen.
Gemäß case
Dokumentation:
Fallanweisungen bestehen aus einer optionalen Bedingung, die sich an der Position eines Arguments befindet
case
, und null oder mehrwhen
Klauseln. Die erstewhen
Klausel, die der Bedingung entspricht (oder die Boolesche Wahrheit ergibt, wenn die Bedingung null ist), "gewinnt", und ihre Code-Zeilengruppe wird ausgeführt. Der Wert der case-Anweisung ist der Wert der erfolgreichenwhen
Klausel odernil
wenn es keine solche Klausel gibt.Eine case-Anweisung kann mit einer
else
Klausel enden . Jedewhen
Anweisung kann mehrere Kandidatenwerte haben, die durch Kommas getrennt sind.
Beispiel:
case x
when 1,2,3
puts "1, 2, or 3"
when 10
puts "10"
else
puts "Some other number"
end
Kürzere Version:
case x
when 1,2,3 then puts "1, 2, or 3"
when 10 then puts "10"
else puts "Some other number"
end
Und wie " Rubys Fallaussage - fortgeschrittene Techniken " Ruby beschreibt case
;
Kann mit Bereichen verwendet werden :
case 5
when (1..10)
puts "case statements match inclusion in a range"
end
## => "case statements match inclusion in a range"
Kann mit Regex verwendet werden :
case "FOOBAR"
when /BAR$/
puts "they can match regular expressions!"
end
## => "they can match regular expressions!"
Kann mit Procs und Lambdas verwendet werden :
case 40
when -> (n) { n.to_s == "40" }
puts "lambdas!"
end
## => "lambdas"
Kann auch mit Ihren eigenen Matchklassen verwendet werden:
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
Abhängig von Ihrem Fall können Sie es vorziehen, einen Hash von Methoden zu verwenden.
Wenn es eine lange Liste von when
s gibt und jeder von ihnen einen konkreten Wert zum Vergleichen hat (kein Intervall), ist es effektiver, einen Hash von Methoden zu deklarieren und dann die relevante Methode aus dem Hash so aufzurufen.
# 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])
Da switch case
immer ein einzelnes Objekt zurückgegeben wird, können wir das Ergebnis direkt drucken:
puts case a
when 0
"It's zero"
when 1
"It's one"
end
Mehrwertiger Wann- und Nichtwertfall:
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
Und eine Lösung für reguläre Ausdrücke hier:
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
case some_string, when /\d/, (stuff), when /[a-zA-Z]/, (stuff), end
(wo ,
bedeutet Newline)
Sie können case
Ausdrücke in Ruby auf zwei verschiedene Arten schreiben :
if
Aussagencase
und jede when
Klausel wird mit dem Ziel verglichen.age = 20
case
when age >= 21
puts "display something"
when 1 == 0
puts "omg"
else
puts "default condition"
end
oder:
case params[:unknown]
when /Something/ then 'Nothing'
when /Something else/ then 'I dont know'
end
Viele gute Antworten, aber ich dachte, ich würde ein Faktoid hinzufügen. Wenn Sie versuchen, Objekte (Klassen) zu vergleichen, stellen Sie sicher, dass Sie eine Raumschiffmethode haben (kein Witz) oder verstehen, wie sie verglichen werden
" Ruby Equality and Object Comparison " ist eine gute Diskussion zu diesem Thema.
<=>
, die verwendet wird, um -1, 0, 1 oder Null zurückzugeben, je nachdem, ob der Vergleich weniger als, gleich, größer als oder nicht vergleichbar zurückgibt. Rubys vergleichbare Moduldokumentation erklärt es.
Wie in vielen der obigen Antworten angegeben, wird der ===
Operator unter der Haube on case
/ when
Anweisungen verwendet.
Hier sind zusätzliche Informationen zu diesem Operator:
===
Viele der in Ruby integrierten Klassen, wie z. B. String, Range und Regexp, bieten ihre eigenen Implementierungen des ===
Operators, auch bekannt als "case-Equality", "Triple Equals" oder "Threequals". Da es in jeder Klasse unterschiedlich implementiert ist, verhält es sich je nach Objekttyp, für den es aufgerufen wurde, unterschiedlich. Im Allgemeinen wird true zurückgegeben, wenn das Objekt auf der rechten Seite zu dem Objekt auf der linken Seite gehört. Beispielsweise kann damit getestet werden, ob ein Objekt eine Instanz einer Klasse (oder einer ihrer Unterklassen) ist.
String === "zen" # Output: => true
Range === (1..2) # Output: => true
Array === [1,2,3] # Output: => true
Integer === 2 # Output: => true
Das gleiche Ergebnis kann mit anderen Methoden erzielt werden, die wahrscheinlich am besten für den Job geeignet sind, wie z. B. is_a?
und instance_of?
.
===
Wenn der ===
Operator für ein Bereichsobjekt aufgerufen wird, gibt er true zurück, wenn der Wert rechts in den Bereich links fällt.
(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
Denken Sie daran, dass der ===
Operator die ===
Methode des linken Objekts aufruft . Ist (1..4) === 3
also gleichbedeutend mit (1..4).=== 3
. Mit anderen Worten, die Klasse des linken Operanden definiert, welche Implementierung der ===
Methode aufgerufen wird, sodass die Operandenpositionen nicht austauschbar sind.
===
Gibt true zurück, wenn die Zeichenfolge rechts mit dem regulären Ausdruck links übereinstimmt.
/zen/ === "practice zazen today" # Output: => true
# is similar to
"practice zazen today"=~ /zen/
Der einzige relevante Unterschied zwischen den beiden obigen Beispielen besteht darin, dass bei einer Übereinstimmung ===
true und =~
eine Ganzzahl zurückgegeben werden, was in Ruby ein wahrer Wert ist. Wir werden bald darauf zurückkommen.
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
$age = 5
case $age
when 0 .. 2
puts "baby"
when 3 .. 6
puts "little child"
when 7 .. 12
puts "child"
when 13 .. 18
puts "youth"
else
puts "adult"
end
Weitere Informationen finden Sie unter " Ruby - if ... else, case, sofern nicht ".
Ich habe angefangen zu verwenden:
a = "secondcase"
var_name = case a
when "firstcase" then "foo"
when "secondcase" then "bar"
end
puts var_name
>> "bar"
In einigen Fällen hilft es, Code zu kompaktieren.
Hash
einer case
Anweisung anstelle einer Anweisung ausgeführt werden.
Keine Unterstützung für reguläre Ausdrücke in Ihrer Umgebung? ZB Shopify Script Editor (April 2018):
[Fehler]: nicht initialisierte Konstante RegExp
Eine Problemumgehung nach einer Kombination von Methoden, die hier und hier bereits behandelt wurden :
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
Ich habe or
s in der Anweisung class method verwendet, da es ||
eine höhere Priorität als hat
.include?
. Wenn Sie ein Rubin-Nazi sind , stellen Sie sich bitte vor, ich hätte dies (item.include? 'A') || ...
stattdessen verwendet. repl.it test.
Es ist wichtig, das Komma ( ,
) in einer when
Klausel hervorzuheben . Es handelt sich ||
um eine if
Anweisung, dh es wird ein ODER- Vergleich und kein UND- Vergleich zwischen den begrenzten Ausdrücken der when
Klausel durchgeführt. Siehe folgende Fallbeschreibung:
x = 3
case x
when 3, x < 2 then 'apple'
when 3, x > 2 then 'orange'
end
=> "apple"
x
ist nicht kleiner als 2, aber der Rückgabewert ist "apple"
. Warum? Weil x
war 3 und seit ',`` acts as an
|| , it did not bother to evaluate the expression
x <2 '.
Sie könnten denken, dass Sie zum Ausführen eines UND etwas wie folgt tun können, aber es funktioniert nicht:
case x
when (3 && x < 2) then 'apple'
when (3 && x > 2) then 'orange'
end
=> nil
Es funktioniert nicht, weil (3 && x > 2)
es als wahr ausgewertet wird, und Ruby nimmt den Wert True und vergleicht ihn x
mit ===
, was nicht wahr ist, da x
es 3 ist.
Um einen &&
Vergleich durchzuführen, müssen Sie case
wie ein if
/ else
block behandeln:
case
when x == 3 && x < 2 then 'apple'
when x == 3 && x > 2 then 'orange'
end
Im Ruby Programming Language-Buch sagt Matz, dass diese letztere Form die einfache (und selten verwendete) Form ist, die nichts weiter als eine alternative Syntax für if
/ elsif
/ ist else
. Unabhängig davon, ob es selten verwendet wird oder nicht, sehe ich keine andere Möglichkeit, mehrere &&
Ausdrücke für eine bestimmte when
Klausel anzuhängen .
if...elsif
? Anscheinend versuchen Sie, eine case-Anweisung und eine Bedingung zu mischen. Warum? Setzen Sie einfach die Bedingung in den when-Block, z. when 3; ( x < 2 ) ? 'apple' : 'orange'
Wir können eine switch-Anweisung für mehrere Bedingungen schreiben.
Zum Beispiel,
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
case
, when
, end
) Zwischen Groß- und können so nicht groß geschrieben.
NoMethodError (undefined method
CASE 'für main: Object) `. Wie @ sondra.kinsey sagte, können Sie keine Großbuchstaben verwenden. Ruby wird denken, dass es eine Konstante ist.
Der case
Anweisungsoperator ist wie switch
in den anderen Sprachen.
Dies ist die Syntax von switch...case
in C:
switch (expression)
{
case constant1:
// statements
break;
case constant2:
// statements
break;
.
.
.
default:
// default statements
}
Dies ist die Syntax von case...when
in 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
Zum Beispiel:
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
Weitere Informationen finden Sie in der case
Dokumentation.