Domanda Come scrivere una dichiarazione switch in Ruby?


Come scrivo un'istruzione switch in Ruby?


1829
2018-06-04 01:18


origine


risposte:


Ruby usa il case espressione anziché.

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 confronta l'oggetto nel when clausola con l'oggetto nel case clausola usando il === operatore. Per esempio, 1..5 === x, e non x === 1..5.

Questo permette sofisticato when clausole come visto sopra. Campi, classi e ogni sorta di cose possono essere testati piuttosto che solo l'uguaglianza.

a differenza di switch dichiarazioni in molte altre lingue, Ruby's case non ha sfumare, quindi non c'è bisogno di terminare ciascuno when con un break. Puoi anche specificare più corrispondenze in un singolo when clausola come when "foo", "bar".


2303
2018-06-04 01:22



case...when si comporta un po 'inaspettatamente durante la gestione delle classi. Ciò è dovuto al fatto che utilizza il === operatore.

Quell'operatore funziona come previsto con i letterali, ma non con le classi:

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

Ciò significa che se vuoi fare un case ... when sulla classe di un oggetto, questo non funzionerà:

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

Stamperà "Non è una stringa".

Fortunatamente, questo è facilmente risolvibile. Il === l'operatore è stato definito in modo che ritorni true se lo usi con una classe e fornisci un'istanza di quella classe come secondo operando:

Fixnum === 1 # => true

In breve, il codice sopra può essere risolto rimuovendo il .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

Oggi ho riscontrato questo problema mentre cercavo una risposta, e questa era la prima pagina visualizzata, quindi ho pensato che sarebbe stato utile ad altri nella mia stessa situazione.


396
2018-04-17 15:20



È fatto da Astuccio in Ruby. Vedi anche questo articolo su Wikipedia.

citato:

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

Un altro esempio:

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

Intorno alla pagina 123 (sto usando Kindle) di The Ruby Programming Lanugage (Prima edizione, O'Reilly), dice il then parola chiave che segue il when le clausole possono essere sostituite con una nuova riga o punto e virgola (proprio come nel if then else sintassi). (Ruby 1.8 consente anche un colon al posto di then... Ma questa sintassi non è più consentita in Ruby 1.9.)


187
2018-06-04 01:20



    caso ... quando

Per aggiungere altri esempi a La risposta di Chuck:

Con parametro:

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

Senza parametro:

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

Per favore, sii consapevole di il problema che kikito avverte.


88
2017-07-05 13:19



Molti linguaggi di programmazione, in particolare quelli derivati ​​da C, supportano il cosiddetto Passa a Fallthrough. Stavo cercando il modo migliore per fare lo stesso in Ruby e ho pensato che potesse essere utile agli altri:

Nei linguaggi di tipo C, la visualizzazione di solito è la seguente:

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, lo stesso può essere ottenuto nel modo seguente:

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

Questo non è strettamente equivalente, perché non è possibile lasciarlo 'a' eseguire un blocco di codice prima di passare a 'b' o 'c', ma per la maggior parte lo trovo abbastanza simile per essere utile allo stesso modo.


64
2017-12-07 12:11



In Ruby 2.0, puoi anche usare lambda in case dichiarazioni, come segue:

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

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

Puoi anche creare facilmente i tuoi comparatori usando una Struct con un'abitudine ===

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

(Esempio tratto da "È possibile utilizzare proc con istruzioni case in Ruby 2.0?".)

Oppure, con una classe completa:

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

(Esempio tratto da "Come funziona un caso clinico rubino e cosa puoi fare con esso".)


63
2017-08-01 00:04



Puoi usare espressioni regolari, come trovare un tipo di stringa:

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 userà l'operando di uguaglianza === per questo (grazie @JimDeville). Ulteriori informazioni sono disponibili su "Operatori rubino"Anche questo può essere fatto usando l'esempio @mmdemirbas (senza parametro), solo questo approccio è più pulito per questi tipi di casi.


47
2017-10-16 12:17



Se sei desideroso di sapere come utilizzare una condizione OR in un caso di switch Ruby:

Quindi, in a case dichiarazione, a , è l'equivalente di || in un if dichiarazione.

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

Molte altre cose che puoi fare con una dichiarazione del caso Ruby


29
2017-07-03 06:46



È chiamato case e funziona come ci si aspetterebbe, oltre a molte altre cose divertenti fornite da === che implementa i test.

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

Ora per un po 'di divertimento:

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

E si scopre che puoi anche sostituire una catena arbitrale if / else (cioè, anche se i test non implicano una variabile comune) con case lasciando fuori l'iniziale case parametro e solo scrivere espressioni in cui la prima corrispondenza è ciò che si desidera.

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