Ruby menggunakan case
ekspresi sebagai gantinya.
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 membandingkan objek dalam when
klausa dengan objek dalam case
klausa menggunakan ===
operator. Misalnya 1..5 === x
,, dan tidak x === 1..5
.
Ini memungkinkan when
klausa canggih seperti yang terlihat di atas. Kisaran, kelas, dan segala macam hal dapat diuji bukan hanya untuk kesetaraan.
Tidak seperti switch
pernyataan dalam banyak bahasa lain, Ruby case
tidak memiliki fall-through , jadi tidak perlu mengakhiri masing when
- masing dengan a break
. Anda juga dapat menentukan beberapa kecocokan dalam satu when
klausa seperti when "foo", "bar"
.
when
danreturn
pernyataan pada baris yang sama:when "foo" then "bar"
switch
pernyataan dalam banyak bahasa lain, Rubycase
TIDAK memiliki fall-through , jadi tidak perlu mengakhiri masingwhen
- masing dengan abreak
.then
. Silakan juga lihat jawaban lainnya.case...when
berperilaku agak tidak terduga ketika menangani kelas. Ini disebabkan oleh fakta bahwa ia menggunakan===
operator.Operator itu berfungsi seperti yang diharapkan dengan literal, tetapi tidak dengan kelas:
Ini berarti bahwa jika Anda ingin melakukan
case ... when
lebih dari satu kelas objek, ini tidak akan berfungsi:Akan mencetak "Ini bukan string atau angka".
Untungnya, ini mudah diselesaikan. The
===
Operator telah didefinisikan sehingga mengembalikantrue
jika Anda menggunakannya dengan kelas dan menyediakan sebuah instance dari kelas yang sebagai operan kedua:Singkatnya, kode di atas dapat diperbaiki dengan menghapus
.class
:Saya mendapatkan masalah ini hari ini sambil mencari jawaban, dan ini adalah halaman pertama yang muncul, jadi saya pikir itu akan bermanfaat bagi orang lain dalam situasi yang sama.
sumber
.class
bagian dalam menarik untuk dicatat, terima kasih. Tentu saja, ini sepenuhnya perilaku yang sesuai (meskipun saya bisa melihat bagaimana mungkin kesalahan umum untuk berpikir yang akan mencetakIt is a string
) ... Anda sedang menguji kelas dari beberapa objek yang arbitrer, bukan objek itu sendiri. Jadi, misalnya:case 'hello'.class when String then "String!" when Class then "Class!" else "Something else" end
hasil dalam:"Class!"
Ini bekerja sama untuk1.class
,{}.class
, dll menjatuhkan.class
, kita mendapatkan"String!"
atau"Something else"
untuk berbagai nilai-nilai.Ini dilakukan menggunakan
case
di Ruby. Lihat juga " Alihkan pernyataan " di Wikipedia.Dikutip:
Contoh lain:
Pada sekitar halaman 123 dari Bahasa Pemrograman Ruby (Edisi 1, O'Reilly) di Kindle saya, dikatakan
then
kata kunci yang mengikutiwhen
klausa dapat diganti dengan baris baru atau titik koma (seperti dalamif then else
sintaksis). (Ruby 1.8 juga memungkinkan titik dua di tempatnyathen
, tetapi sintaks ini tidak lagi diizinkan di Ruby 1.9.)sumber
when (-1.0/0.0)..-1 then "Epic fail"
type = #{score}
setiap baris, saya hanya dapat menyalin apa yang Anda lakukan. Jauh lebih elegan. Saya juga menyukai one-liner yang jauh lebih baik (jika mungkin)kasus ... kapan
Untuk menambahkan lebih banyak contoh ke jawaban Chuck :
Dengan parameter:
Tanpa parameter:
Harap waspadai " Cara menulis pernyataan beralih di Ruby " yang diperingatkan kikito.
sumber
or
Banyak bahasa pemrograman, terutama yang berasal dari C, memiliki dukungan untuk apa yang disebut Switch Fallthrough . Saya sedang mencari cara terbaik untuk melakukan hal yang sama di Ruby dan berpikir itu mungkin berguna bagi orang lain:
Dalam bahasa seperti C, fallthrough biasanya terlihat seperti ini:
Di Ruby, hal yang sama dapat dicapai dengan cara berikut:
Ini tidak sepenuhnya setara, karena tidak mungkin untuk
'a'
mengeksekusi blok kode sebelum jatuh ke'b'
atau'c'
, tetapi sebagian besar saya merasa cukup mirip untuk berguna dengan cara yang sama.sumber
Di Ruby 2.0, Anda juga dapat menggunakan lambdas dalam
case
pernyataan, sebagai berikut:Anda juga dapat membuat komparator sendiri dengan mudah menggunakan Struct dengan custom
===
(Contoh diambil dari " Bisakah procs digunakan dengan pernyataan kasus di Ruby 2.0? ".)
Atau, dengan kelas lengkap:
(Contoh diambil dari " Bagaimana Pernyataan Kasus Ruby Bekerja Dan Apa Yang Dapat Anda Lakukan dengannya ".)
sumber
Anda dapat menggunakan ekspresi reguler, seperti menemukan jenis string:
Ruby
case
akan menggunakan operan kesetaraan===
untuk ini (terima kasih @JimDeville). Informasi tambahan tersedia di " Operator Ruby ". Ini juga dapat dilakukan dengan menggunakan contoh @mmdemirbas (tanpa parameter), hanya pendekatan ini yang lebih bersih untuk jenis kasus ini.sumber
Jika Anda ingin tahu cara menggunakan kondisi ATAU dalam wadah sakelar Ruby:
Jadi, dalam sebuah
case
pernyataan, a,
sama dengan||
dalam sebuahif
pernyataan.Lihat " Bagaimana Pernyataan Kasus Ruby Bekerja Dan Apa Yang Dapat Anda Lakukan dengannya ".
sumber
Ini disebut
case
dan berfungsi seperti yang Anda harapkan, ditambah banyak hal menyenangkan lainnya===
yang mengimplementasikan tes.Sekarang untuk bersenang-senang:
Dan ternyata Anda juga dapat mengganti rantai arbitrer if / else (yaitu, bahkan jika tes tidak melibatkan variabel umum) dengan
case
dengan meninggalkancase
parameter awal dan hanya menulis ekspresi di mana kecocokan pertama adalah yang Anda inginkan.sumber
Ruby menggunakan
case
pergantian pernyataan penulisan.Sesuai
case
dokumentasi:Contoh:
Versi lebih pendek:
Dan seperti " Pernyataan kasus Ruby - teknik-teknik canggih " menggambarkan Ruby
case
;Dapat digunakan dengan Ranges :
Dapat digunakan dengan Regex :
Dapat digunakan dengan Procs dan Lambdas :
Juga, dapat digunakan dengan kelas pertandingan Anda sendiri:
sumber
Tergantung pada kasus Anda, Anda dapat memilih untuk menggunakan metode hash.
Jika ada daftar panjang
when
s dan masing-masing memiliki nilai konkret untuk dibandingkan dengan (bukan interval), akan lebih efektif untuk mendeklarasikan hash metode dan kemudian memanggil metode yang relevan dari hash seperti itu.sumber
Karena
switch case
selalu mengembalikan satu objek, kami dapat langsung mencetak hasilnya:sumber
Kasus multi-nilai kapan dan tanpa nilai:
Dan solusi ekspresi reguler di sini:
sumber
case some_string, when /\d/, (stuff), when /[a-zA-Z]/, (stuff), end
(di mana,
berarti baris baru)Anda dapat menulis
case
ekspresi dengan dua cara berbeda di Ruby:if
pernyataancase
dan setiapwhen
klausa dibandingkan dengan target.atau:
sumber
Anda dapat melakukannya seperti ini dengan cara yang lebih alami,
sumber
Banyak jawaban bagus tapi saya pikir saya akan menambahkan satu factoid .. Jika Anda mencoba untuk membandingkan objek (Kelas) pastikan Anda memiliki metode kapal ruang (bukan lelucon) atau mengerti bagaimana mereka dibandingkan
" Ruby Equality And Object Comparison " adalah diskusi yang baik tentang topik tersebut.
sumber
<=>
, yang digunakan untuk mengembalikan -1, 0, 1, atau nil tergantung pada apakah perbandingan mengembalikan kurang dari, sama, lebih besar dari, atau tidak sebanding masing-masing. Dokumentasi modul Sebanding Ruby menjelaskannya.Sebagaimana dinyatakan dalam banyak jawaban di atas,
===
operator digunakan di bawah kap pernyataancase
/when
pernyataan.Berikut ini informasi tambahan tentang operator itu:
Operator kesetaraan kasus:
===
Banyak kelas bawaan Ruby, seperti String, Range, dan Regexp, menyediakan implementasi
===
operator mereka sendiri , juga dikenal sebagai "kesetaraan kasus", "triple equals" atau "threequals". Karena diimplementasikan secara berbeda di setiap kelas, ia akan berperilaku berbeda tergantung pada jenis objek yang dipanggil. Secara umum, ia mengembalikan true jika objek di sebelah kanan "milik" atau "adalah anggota" objek di sebelah kiri. Misalnya, ini dapat digunakan untuk menguji apakah suatu objek adalah turunan dari kelas (atau salah satu dari sub-kelasnya).Hasil yang sama dapat dicapai dengan metode lain yang mungkin paling cocok untuk pekerjaan itu, seperti
is_a?
daninstance_of?
.Rentang Implementasi
===
Ketika
===
operator dipanggil pada objek jangkauan, itu mengembalikan true jika nilai di sebelah kanan jatuh dalam rentang di sebelah kiri.Ingat bahwa
===
operator memanggil===
metode objek kiri. Begitu(1..4) === 3
juga dengan(1..4).=== 3
. Dengan kata lain, kelas operan kiri akan menentukan implementasi===
metode yang akan dipanggil, sehingga posisi operan tidak dapat dipertukarkan.Implementasi Regexp dari
===
Mengembalikan nilai true jika string di sebelah kanan cocok dengan ekspresi reguler di sebelah kiri.
Satu-satunya perbedaan yang relevan antara dua contoh di atas adalah bahwa, ketika ada kecocokan,
===
mengembalikan true dan=~
mengembalikan integer, yang merupakan nilai sebenarnya di Ruby. Kami akan segera kembali ke sini.sumber
sumber
Lihat " Ruby - if ... else, case, kecuali " untuk informasi lebih lanjut.
sumber
Saya sudah mulai menggunakan:
Ini membantu kode ringkas dalam beberapa kasus.
sumber
Hash
, daripadacase
pernyataan.Tidak ada dukungan untuk ekspresi reguler di lingkungan Anda? Misalnya Editor Skrip Shopify (April, 2018):
Solusi yang mengikuti kombinasi metode yang sebelumnya telah dibahas di sini dan di sini :
Saya menggunakan
or
s dalam pernyataan metode kelas karena||
memiliki prioritas lebih tinggi daripada.include?
. Jika Anda seorang ruby-nazi , tolong bayangkan saya menggunakan ini(item.include? 'A') || ...
sebagai gantinya. tes repl.it.sumber
Sangat penting untuk menekankan koma (
,
) dalamwhen
klausa. Ini bertindak sebagai||
sebuahif
pernyataan, yaitu, hal itu merupakan OR perbandingan dan bukan DAN perbandingan antara ekspresi dibatasi dariwhen
klausa. Lihat pernyataan kasus berikut:x
tidak kurang dari 2, namun nilai kembalinya adalah"apple"
. Mengapa? Karenax
3 dan sejak',`` acts as an
||, it did not bother to evaluate the expression
x <2 '.Anda mungkin berpikir bahwa untuk melakukan DAN , Anda dapat melakukan sesuatu seperti ini di bawah, tetapi tidak berhasil:
Itu tidak bekerja karena
(3 && x > 2)
mengevaluasi ke true, dan Ruby mengambil nilai True dan membandingkannyax
dengan===
, yang tidak benar, karenax
adalah 3.Untuk melakukan
&&
perbandingan, Anda harus memperlakukancase
sepertiif
/else
blok:Dalam buku Bahasa Pemrograman Ruby, Matz mengatakan formulir terakhir ini adalah formulir sederhana (dan jarang digunakan), yang tidak lebih dari sintaks alternatif untuk
if
/elsif
/else
. Namun, apakah itu jarang digunakan atau tidak, saya tidak melihat cara lain untuk melampirkan banyak&&
ekspresi untukwhen
klausa yang diberikan .sumber
if...elsif
? Tampaknya Anda mencoba mencampur pernyataan kasus dan kondisi. Mengapa? Masukkan saja kondisional ke dalam blok when, mis.when 3; ( x < 2 ) ? 'apple' : 'orange'
Kita dapat menulis pernyataan beralih untuk berbagai kondisi.
Sebagai contoh,
sumber
case
,when
,end
) Adalah case-sensitive dan tidak bisa huruf besar seperti ini.NoMethodError (undefined method
CASE 'untuk main: Object) `. Seperti yang dikatakan @ sondra.kinsey, Anda tidak dapat menggunakan huruf besar. Ruby akan berpikir itu adalah KONSTAN.The
case
Operator pernyataan sepertiswitch
dalam bahasa-bahasa lain.Ini adalah sintaks dari
switch...case
dalam C:Ini adalah sintaks
case...when
dalam Ruby:Sebagai contoh:
Untuk informasi lebih lanjut, lihat
case
dokumentasi.sumber