Scala-value <不是AnyVal的成员

时间:2018-11-16 09:53:38

标签: scala functional-programming

这是我的代码。我在第二种情况下出现了编译错误:

  

错误:(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 :(得分:5)

这是因为元组数组由两种不同的类型组成: image.layer.cornerRadius = image.layer.frame.width / 2 button.layer.cornerRadius = button.layer.frame.width / 2 Tuple2[String, Int]。这些类型由编译器推断,然后元组数组的干扰类型为Tuple2[String, Double]。当您使用Double表示形式时,编译器可以创建Tuple2[String, AnyVal]

答案 1 :(得分:5)

查看REPL:

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的有效函数。

当您将Plain定义为Tuple2(“ Plain”,1)时,两个Tuple的第二部分具有不同的类型(IntDouble),因此结果列表为{{1} }:

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)) <无效。

答案 2 :(得分:2)

由于无法在<类型上执行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是{{1 }}(非数字),将无法编译。因此,您在编译时会遇到异常。

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