Лучший способ проверить ценность опциона?

Я часто нахожусь с Option[T] для некоторого типа T и хочу проверить значение параметра по сравнению с некоторым значением. Например:

val opt = Some("oxbow")
if (opt.isDefined && opt.get == "lakes") 
   //do something

Следующий код эквивалентен и устраняет необходимость проверки существования значения параметра

if (opt.map(_ == "lakes").getOrElse(false))
 //do something

Однако это кажется мне менее читаемым. Другие возможности:

if (opt.filter(_ == "lakes").isDefined)

if (opt.find(_ == "lakes").isDefined) //uses implicit conversion to Iterable

Но я не думаю, что они четко выражают намерение, которое было бы лучше, чем:

if (opt.isDefinedAnd(_ == "lakes"))

У кого-нибудь есть лучший способ сделать этот тест?


person oxbow_lakes    schedule 23.10.2009    source источник


Ответы (5)


Как насчет

if (opt == Some("lakes"))

Это ясно и прямо выражает намерение.

person Walter Chang    schedule 23.10.2009
comment
Иногда самое простое решение самое лучшее :) - person Ula Krukar; 23.10.2009
comment
Разве это не будет компилироваться, даже если opt не является опцией? - person cdmckay; 25.06.2015

Для Scala 2.11 вы можете использовать Some(foo).contains(bar)

person marconi    schedule 30.06.2014
comment
Я так обычно иду. Я просто не могу понять, что этот ответ не принят как правильный. - person Boris; 05.11.2020

Уолтер Чанг FTW, но вот еще одна неуклюжая альтернатива:

Some(2) exists (_ == 2)
person Daniel C. Sobral    schedule 23.10.2009
comment
Дэниел, это ужасно! :-) - person oxbow_lakes; 23.10.2009
comment
Мне это действительно нравится; избегает одного создания и неприменимого, и все же является кратким - person HRJ; 25.10.2009
comment
Это на самом деле стандартный способ, насколько я понимаю. - person psp; 27.10.2009
comment
Немного жаль, что Option неявно не преобразуется в Seq, что позволило бы использовать Some(1) contains 1. - person retronym; 16.01.2010
comment
@retrony Да, но, с другой стороны, Some(2).toSeq contains 2 работает. Слишком круглогодично, на мой вкус. - person Daniel C. Sobral; 17.01.2010
comment
Возможно, contains следует добавить непосредственно в Option. - person retronym; 17.01.2010
comment
@retronim На самом деле неплохая идея. Перейдите на страницу lampsvn.epfl.ch/trac/scala и откройте билет на улучшение, если вам это действительно нужно. об этом. - person Daniel C. Sobral; 17.01.2010
comment
Кто-то наконец открыл этот билет: issues.scala-lang.org/browse/SI-6064. - person Seth Tisue; 12.07.2012

Вы также можете использовать для понимания:

for {val v <- opt if v == "lakes"}
  // do smth with v
person Alexander Azarov    schedule 23.10.2009

Я думаю, что сопоставление с образцом также можно использовать. Таким образом, вы извлекаете интересное значение напрямую:

val opt = Some("oxbow")
opt match {
  case Some(value) => println(value) //Doing something
}
person Jostein Stuhaug    schedule 23.10.2009
comment
Это не проверяет значение - только то, что оно присутствует. Причина, по которой я хочу избежать match, заключается в том, что это, следовательно, приводит к тому, что логика else находится в нескольких местах (т.е. case None и если значение не является желаемым) - person oxbow_lakes; 23.10.2009