Как мне написать switch
заявление в Ruby?
2080
Как мне написать switch
заявление в Ruby?
Ruby вместо этого использует case
выражение .
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 сравнивает объект в when
предложении с объектом в case
предложении, используя ===
оператор. Например 1..5 === x
, и нет x === 1..5
.
Это учитывает сложные when
пункты как замечено выше. Диапазоны, классы и все виды вещей могут быть проверены, а не только на равенство.
В отличие от switch
выражений во многих других языках, в Ruby case
нет провала , поэтому нет необходимости заканчивать каждое when
символом a break
. Вы также можете указать несколько совпадений в одном when
предложении, как when "foo", "bar"
.
when
andreturn
в одну строку:when "foo" then "bar"
switch
операторов во многих других языках, Ruby'scase
не имеет провала , поэтому нет необходимости заканчивать каждоеwhen
символом abreak
.then
. Пожалуйста, посмотрите также другие ответы.case...when
ведет себя немного неожиданно при обработке классов. Это связано с тем, что его использует===
оператор.Этот оператор работает, как и ожидалось, с литералами, но не с классами:
Это означает, что если вы хотите сделать
case ... when
над классом объекта, это не будет работать:Будет напечатано «Это не строка или число».
К счастью, это легко решается.
===
Оператор был определен так , что он возвращается ,true
если вы используете его с классом и поставить экземпляр этого класса в качестве второго операнда:Короче говоря, приведенный выше код можно исправить, удалив
.class
:Я столкнулся с этой проблемой сегодня, когда искал ответ, и это была первая появившаяся страница, поэтому я подумал, что она будет полезна другим в моей ситуации.
источник
.class
участие в Интересно отметить, спасибо. Конечно, это вполне подходящее поведение (хотя я мог видеть, как это может быть распространенной ошибкой думать, что это напечатало быIt is a string
) ... вы тестируете класс какого-то произвольного объекта, а не сам объект. Так, например:case 'hello'.class when String then "String!" when Class then "Class!" else "Something else" end
результаты:"Class!"
Это работает так же для1.class
,{}.class
и т.д. Dropping.class
, мы получаем"String!"
или"Something else"
для этих различных значений.Это делается с помощью
case
Ruby. Также см. « Смена оператора » в Википедии.Цитируется:
Другой пример:
На странице 123 «Языка программирования Ruby» (1-е издание, O'Reilly) на моем Kindle говорится, что
then
ключевое слово послеwhen
предложений можно заменить на новую строку или точку с запятой (как вif then else
синтаксисе). (Ruby 1.8 также допускает двоеточие вместоthen
, но этот синтаксис больше не разрешен в Ruby 1.9.)источник
when (-1.0/0.0)..-1 then "Epic fail"
type = #{score}
каждую строку, я могу просто скопировать то, что вы сделали. Гораздо более элегантно, мне также нравятся однострочники намного лучше (если это возможно)случай ... когда
Чтобы добавить больше примеров к ответу Чака :
С параметром:
Без параметра:
Пожалуйста, имейте в виду " Как написать оператор switch в Ruby ", о котором kikito предупреждает.
источник
or
Многие языки программирования, особенно те, что происходят от C, поддерживают так называемый Switch Fallthrough . Я искал лучший способ сделать то же самое в Ruby и подумал, что это может быть полезно для других:
В C-подобных языках падение обычно выглядит так:
В Ruby то же самое может быть достигнуто следующим образом:
Это не совсем эквивалентно, потому что невозможно
'a'
выполнить блок кода перед тем, как перейти к'b'
или'c'
, но по большей части я нахожу его достаточно похожим, чтобы быть полезным таким же образом.источник
В Ruby 2.0 вы также можете использовать лямбды-
case
выражения в следующих выражениях:Вы также можете легко создавать свои собственные компараторы, используя Struct с пользовательскими
===
(Пример взят из « Можно ли использовать процы с операторами case в Ruby 2.0? ».)
Или с полным классом:
(Пример взят из статьи « Как работает оператор Ruby и что вы можете с ним сделать ».)
источник
Вы можете использовать регулярные выражения, такие как поиск типа строки:
Ruby's
case
будет использовать===
для этого операнд равенства (спасибо @JimDeville). Дополнительная информация доступна на " Рубин Операторы ". Это также можно сделать с помощью примера @mmdemirbas (без параметра), только этот подход более чист для таких случаев.источник
Если вы хотите знать, как использовать условие ИЛИ в случае переключения Ruby:
Таким образом, в
case
утверждении a,
является эквивалентом||
вif
утверждении.Смотрите " Как работает Ruby Case case и что вы можете с ним сделать ".
источник
Он называется
case
и работает так, как и следовало ожидать, плюс еще много забавных вещей, благодаря===
которым реализуются тесты.Теперь для развлечения:
И оказывается, что вы также можете заменить произвольную цепочку if / else (то есть, даже если в тестах нет общей переменной)
case
, пропустив начальныйcase
параметр и просто написав выражения, где первое совпадение - это то, что вам нужно.источник
Ruby использует
case
для написания операторов switch.Согласно
case
документации:Пример:
Укороченная версия:
И как « утверждение случая Руби - продвинутые методы » описывает Руби
case
;Может использоваться с диапазонами :
Может использоваться с Regex :
Может использоваться с Procs и Lambdas :
Кроме того, может использоваться с вашими собственными классами соответствия:
источник
В зависимости от вашего случая, вы можете предпочесть использовать хэш методов.
Если существует длинный список
when
s, и у каждого из них есть конкретное значение для сравнения (не с интервалом), будет эффективнее объявить хеш методов и затем вызвать соответствующий метод из хеша, подобного этому.источник
Поскольку
switch case
всегда возвращает один объект, мы можем напрямую напечатать его результат:источник
Случай с несколькими значениями, когда и без значения:
И решение с регулярным выражением здесь:
источник
case some_string, when /\d/, (stuff), when /[a-zA-Z]/, (stuff), end
(где,
означаетВы можете написать
case
выражения двумя разными способами в Ruby:if
заявленийcase
и каждоеwhen
предложение сравнивается с целью.или:
источник
Вы можете сделать это более естественным образом,
источник
Много хороших ответов, но я подумал, что добавлю один фактоид. Если вы пытаетесь сравнивать объекты (классы), убедитесь, что у вас есть метод космического корабля (а не шутка) или вы понимаете, как они сравниваются
" Рубиновое равенство и сравнение объектов " - хорошая дискуссия на эту тему.
источник
<=>
, который используется для возврата -1, 0, 1 или nil в зависимости от того, возвращает ли сравнение меньше, равно, больше или не сопоставимо соответственно. В документации Ruby Comparable module это объясняется.Как указано во многих из приведенных выше ответов,
===
оператор используется под капотом наcase
/when
операторов.Вот дополнительная информация об этом операторе:
Оператор равенства случая:
===
Многие из встроенных в Ruby классов, такие как String, Range и Regexp, предоставляют свои собственные реализации
===
оператора, также известные как «case-равенства», «тройное равенство» или «тройное равенство». Поскольку он реализован по-разному в каждом классе, он будет вести себя по-разному в зависимости от типа объекта, к которому он был вызван. Как правило, он возвращает true, если объект справа «принадлежит» или «является членом» объекта слева. Например, его можно использовать для проверки того, является ли объект экземпляром класса (или одного из его подклассов).Тот же результат может быть достигнут с помощью других методов, которые, вероятно, лучше всего подходят для работы, таких как
is_a?
иinstance_of?
.Диапазон реализации
===
Когда
===
оператор вызывается для объекта диапазона, он возвращает истину, если значение справа попадает в диапазон слева.Помните, что
===
оператор вызывает===
метод левого объекта. Так(1..4) === 3
эквивалентно(1..4).=== 3
. Другими словами, класс левого операнда определит, какая реализация===
метода будет вызвана, поэтому позиции операнда не являются взаимозаменяемыми.Внедрение регулярных выражений
===
Возвращает true, если строка справа соответствует регулярному выражению слева.
Единственное существенное различие между двумя приведенными выше примерами состоит в том, что при наличии совпадения
===
возвращается значение true и=~
возвращается целое число, которое является истинным значением в Ruby. Мы скоро вернемся к этому.источник
источник
Смотрите " Ruby - если ... еще, case, если только " для получения дополнительной информации.
источник
Я начал использовать:
Это помогает компактный код в некоторых случаях.
источник
Hash
, а неcase
оператора.Нет поддержки регулярных выражений в вашей среде? Например, редактор сценариев Shopify (апрель 2018 г.):
Обходной путь, следующий за комбинацией методов, уже описанных здесь и здесь :
Я использовал
or
s в выражении метода класса, поскольку||
имеет более высокий приоритет, чем.include?
. Если вы рубин-нацист , пожалуйста, представьте, что я использовал это(item.include? 'A') || ...
вместо этого. Репл.ит тест.источник
Важно подчеркнуть запятую (
,
) вwhen
предложении. Он действует как||
изif
заявления, то есть, он делает или сравнение и не И сравнение между разделителями выраженийwhen
пункта. Смотрите следующее описание случая:x
не менее 2, но возвращаемое значение"apple"
. Почему? Потому чтоx
было 3, а так как',`` acts as an
||, it did not bother to evaluate the expression
х <2 '.Вы можете подумать, что для выполнения AND , вы можете сделать что-то вроде этого ниже, но это не работает:
Это не работает, потому что
(3 && x > 2)
оценивается как true, а Ruby принимает значение True и сравнивает егоx
с значением===
, которое не соответствует истине, посколькуx
равно 3.Чтобы сделать
&&
сравнение, вам нужно рассматриватьcase
какif
/else
блок:В книге Ruby Programming Language Матц говорит, что эта последняя форма является простой (и редко используемой) формой, которая является не чем иным, как альтернативным синтаксисом для
if
/elsif
/else
. Однако, используется ли это редко или нет, я не вижу другого способа присоединить несколько&&
выражений для данногоwhen
предложения.источник
if...elsif
? Похоже, вы пытаетесь смешать заявление случая и условие. Почему? Просто поместите условную внутри группы При блоке, например.when 3; ( x < 2 ) ? 'apple' : 'orange'
Мы можем написать оператор switch для нескольких условий.
Например,
источник
case
,when
,end
) Чувствительны к регистру и не может быть в верхнем регистре , как это.NoMethodError (undefined method
CASE 'для main: Object) `. Как сказал @ sondra.kinsey, вы не можете использовать верхний регистр. Руби будет думать, что это ПОСТОЯННО.case
Оператор оператор подобенswitch
и в других языках.Это синтаксис
switch...case
в C:Это синтаксис
case...when
в Ruby:Например:
Для получения дополнительной информации см.
case
Документацию.источник