#scala #class #pattern-matching #case #traits
#scala #класс #Сопоставление с образцом #случай #Трейты
Вопрос:
У меня есть следующая черта в моем проекте Scala
sealed trait Value
case class Float(f: Double) extends Value
case class Bool(b: Boolean) extends Value
case object Error extends Value
Позже у меня есть значение lst: List[Value]
.
Я пытаюсь получить значение первого элемента списка с lst.head.f
помощью, но я получаю следующую ошибку Cannot resolve symbol f
.
Из того, что я собрал из других вопросов о переполнении стека по аналогичной теме, это должно работать, но это не так.
Комментарии:
1. Что должно
lst.head.f
выдаватьlst = List(Bool(true))
илиlst = List(Error)
?2. Возможно, вы хотите
lst.head match { case Float(f) => f }
илиlst.head match { case x: Float => x.f }
.3. Что делать, если список пуст? что, если первое значение не является плавающим ?
4. Поскольку вы сказали, что вы новичок в Scala , позвольте мне дать вам совет. Scala — ЭТО НЕ другой язык ООП, для которого вам нужно только изучить его синтаксис. Scala — это смесь ООП и FP, поэтому вам нужно многому научиться заново, особенно тому, как разрабатывать программы и как подходить к проблемам. Такие вещи, как неизменность, опция, функции более высокого порядка и т. Д., Являются шаблонами проектирования функциональных языков. Поэтому я бы посоветовал вам взять книгу или найти курс, который поможет вам не только разобраться в синтаксисе, но и в мышлении функционального программиста.
Ответ №1:
Код должен допускать, чтобы значение lst
было пустым или первым Value
было что-то другое, чем Float
. Этот код будет безопасно извлекать любое Double
значение в Option
:
val optF: Option[Double] = lst.headOption.collect{ case Float(f) => f}
Это вернет Some
, если в списке был первый элемент, и он был a Float
, в противном случае он вернется None
. Используйте стандартные Option
операции для проверки на наличие ошибки или просто получите значение с помощью getOrElse
.
Комментарии:
1. Можете ли вы объяснить, что
Option
это такое. Я новичок в Scala2. Вероятно, лучше всего прочитать некоторые статьи, но
Option
это способ обработки значений, которые могут быть или не быть там. Это типобезопасная альтернатива использованиюnull
или некоторому другому недопустимому значению.Option
Значение присваивается либоNone
в том случае, если его там нет, либоSome(value)
в том случае, если оно есть. Вы можете использоватьgetOrElse(default)
onOption
для извлечения значения, если оно есть, или получить значение по умолчанию, если его там нет. Это похоже на коллекцию с 0 или 1 элементами, поэтому многие методы сбора также работают, напримерisEmpty
.3. @ZacharyElkins alvinalexander.com/scala /…
Ответ №2:
У вас lst
есть тип Value
, который не определяет значение f
.
Что, если первый элемент в списке имеет тип Bool
? Это явно тоже не определяет f
.
Каков ваш вариант использования здесь? Вы можете либо убедиться, что все подтипы Values
define f
с
sealed trait Value {
def f
}
или просто получите f
, если тип Float
lst.head match {
case Float(f) =>
// Do something with
f
case Bool(b) =>
// Do something with
b
case e: Error =>
// Do something with the error
}
Ответ №3:
Это было так просто, как следующее:
val v1 = lst(0) match => {
Float(f) => f
Bool(b) => b
_ => "Something else"
}
Я просто думал об этом.
Комментарии:
1. После того, как вы исправите синтаксические ошибки в опубликованном коде, посмотрите на тип вашего
v1
результата. Не очень полезное решение.