与scala中使用的类型参数的用法混淆
我有以下简单的代码:与scala中使用的类型参数的用法混淆,scala,Scala,我有以下简单的代码: trait MyBox[T] { def capacity: Double } case class FruitBox[T](fruit: Int) extends MyBox[T] { override def capacity = 1.0 } object FruitBox { def apply[T](fruit: Int): FruitBox[T] = new FruitBox[T](fruit) } 以下代码也是有效的,因为我省略了类型参数T
trait MyBox[T] {
def capacity: Double
}
case class FruitBox[T](fruit: Int) extends MyBox[T] {
override def capacity = 1.0
}
object FruitBox {
def apply[T](fruit: Int): FruitBox[T] = new FruitBox[T](fruit)
}
以下代码也是有效的,因为我省略了类型参数T
case class FruitBox[T](fruit: Int) extends MyBox { //T is omitted for MyBox[T]
override def capacity = 1.0
}
object FruitBox{
def apply[T](fruit: Int): FruitBox[T] = new FruitBox(fruit) //T is omitted for new FruitBox
}
我会问为什么我可以省略类型参数?这背后的原因是什么?在我看来,在scala中,参数化类型必须具有类型参数才能成为具体类型。为了避免可能的误解,这里不编译:
trait MyBox[T] {
def capacity: Double
}
case class FruitBox[T](fruit: Int) extends MyBox {
override def capacity = 1.0
}
您不能在这里省略[t]
,您将得到“error:trait MyBox接受类型参数”
问题的第二部分与
MyBox
或继承无关。这将以完全相同的方式工作,原因完全相同:
case class FruitBox[T](fruit: Int)
object FruitBox{
def apply[T](fruit: Int): FruitBox[T] = new FruitBox(fruit)
}
类型参数可以从代码中省略,但右侧的表达式new-FruitBox(fruit)
仍然是正确的类型FruitBox[T]
。这是因为返回类型水果盒[T]
可用于推断=
-符号后面的表达式类型。编译器自动添加[T]
,因此上述定义只是
def apply[T](fruit: Int): FruitBox[T] = new FruitBox[T](fruit)
这类似于以下示例:
var foo: Set[String] = Set.empty
即使方法empty
再次由类型参数化,也可以从声明变量的类型推断此类型参数,以便代码有效地变为:
var foo: Set[String] = Set.empty[String]
类型推断会在其他几种情况下起作用,最显著的是:
- 当表达式
作为一个方法的参数出现时,该方法在该位置需要一个类型为new-FruitBox(i)
的参数,那么编译器将自动推断FruitBox[SomeType]
实际上代表new-FruitBox(i)
new-FruitBox[SomeType](i)
- 当您在
,编译器将自动将中使用类型归属时(新的水果盒(42):水果盒[String])
添加到[String]
调用中新的