Извлечение значения класса Scala Case

#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 это такое. Я новичок в Scala

2. Вероятно, лучше всего прочитать некоторые статьи, но Option это способ обработки значений, которые могут быть или не быть там. Это типобезопасная альтернатива использованию null или некоторому другому недопустимому значению. Option Значение присваивается либо None в том случае, если его там нет, либо Some(value) в том случае, если оно есть. Вы можете использовать getOrElse(default) on Option для извлечения значения, если оно есть, или получить значение по умолчанию, если его там нет. Это похоже на коллекцию с 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 результата. Не очень полезное решение.