这是我的代码。我在第二种情况下出现了编译错误:
错误:(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)
终于可以了。 这让我感到困惑,我想知道为什么?
答案 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的第二部分具有不同的类型(Int
与Double
),因此结果列表为{{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
。