Scala - значение <не является членом AnyVal - PullRequest
0 голосов
/ 16 ноября 2018

Вот мой код. Я получил ошибку компиляции во втором предложении case:

Ошибка: (92, 26) значение <не является членом AnyVal регистр x если x._2 <2 => "цена ниже 2"

def tupleMatch: Unit = {
  val donut = Tuple2("Donut", 2.5)
  val plain = Tuple2("Plain", 1.0)
  val tuples = List(donut, plain)
  tuples.foreach { tuple => 
    val toPrint = tuple match {
      case ("Donut", price) => s"price of Donut is ${donut._2}"
      case (_, price) if price < 2 => "price under 2"
      case _ => "other"
    }
    println(toPrint)

  }
}

После того, как я изменюсь

val plain = Tuple2("Plain", 1)

до

val plain = Tuple2("Plain", 1.0)

это наконец работает. Это меня смущает, я хочу знать почему?

Ответы [ 3 ]

0 голосов
/ 16 ноября 2018

Глядя на ответ:

scala> val donut = Tuple2("Donut", 2.5)
donut: (String, Double) = (Donut,2.5)

scala> val plain = Tuple2("Plain", 1.0)
plain: (String, Double) = (Plain,1.0)

scala> val tuples = List(donut, plain)
tuples: List[(String, Double)] = List((Donut,2.5), (Plain,1.0))

Поскольку два кортежа имеют одинаковый тип (String, Double), список имеет тип List[(String, Double)]. < является допустимой функцией для Double.

Когда вы определяете обычный как Tuple2 («Обычный», 1), вторая часть двух кортежей имеет разные типы (Int против Double), поэтому результирующий список будет List[(String, AnyVal)]:

scala> val donut = Tuple2("Donut", 2.5)
donut: (String, Double) = (Donut,2.5)

scala> val plain = Tuple2("Plain", 1)
plain: (String, Int) = (Plain,1)

scala> val tuples = List(donut, plain)
tuples: List[(String, AnyVal)] = List((Donut,2.5), (Plain,1))

... и < не является допустимой функцией для AnyVal.

0 голосов
/ 16 ноября 2018

Это из-за того, что мы не можем выполнить < (меньше чем) операцию с типом AnyVal.

scala> val donut = Tuple2("Donut", 2.5)
donut: (String, Double) = (Donut,2.5)

scala> val plain = Tuple2("Plain", 1)  
plain: (String, Int) = (Plain,1)

Как вы можете видеть выше. Когда вы определяете Tuple2("Donut", 2.5), 2.5 выводится на Double, а в Tuple2("Plain", 1), 1 выводится как Int, поскольку вы не указали тип явно.

Теперь, когда вы создаете список этих кортежей, из-за типа списка вывода тип будет (String, AnyVal).

scala> val tuples = List(donut, plain)
tuples: List[(String, AnyVal)] = List((Donut,2.5), (Plain,1))

Теперь, когда вы выполняете case x if x._2 < 2, вы фактически сравниваете тип AnyVal с числом, т.е. 2, что невозможно, поскольку компилятор считает, что x._2 - это AnyVal (не число) и не будет компиляции. Поэтому вы получаете исключение во время компиляции.

<console>:22: error: value < is not a member of AnyVal
                 case x if (x._2 < 2) => "price under 2"

Во втором случае, т. Е. Когда вы определили кортеж как Tuple2("Plain", 1.0), его тип номера также выводится как Double.

scala> val donut = Tuple2("Donut", 2.5)
donut: (String, Double) = (Donut,2.5)

scala> val plain = Tuple2("Plain", 1.0)
plain: (String, Double) = (Plain,1.0)

И, когда вы создаете список кортежей, так как оба имеют одинаковый тип, т.е. (String, Double), список будет иметь тип List[(String, Double)].

scala> val tuples = List(donut, plain)
tuples: List[(String, Double)] = List((Donut,2.5), (Plain,1.0))

И x._2 < 2 будут компилироваться правильно, так как вы вызываете < в двойном (число).

0 голосов
/ 16 ноября 2018

Это потому, что ваш массив кортежей состоит из двух разных типов: Tuple2[String, Int] и Tuple2[String, Double].Эти типы выводятся компилятором, и тогда тип массива кортежей с помехами равен Tuple2[String, AnyVal].Когда вы помещаете двойное представление, компилятор может создать Tuple2[String, Double].

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...