假设我创建了一个单一参数泛型方法:
trait MyTrait[T] {
def method():T
}
然后扩展它并进行参数化。这样:
class MyClass extends MyTrait[java.lang.String] {
def method() = "foo"
}
与此相同:
class MyClass extends MyTrait[String] {
def method() = "foo"
}
但是,当你创建一个特征参数化lambda的特征方法时:
trait MyTrait {
def apply[T](input:()=>T):T
}
然后你没那么幸运。这样:
class MyClass extends MyTrait {
def apply(input:()=>java.lang.String) = "foo"
}
会导致这个:
Error:(25, 45) type mismatch;
found : java.lang.String("foo")
required: String
def apply[String](input:()=>String) = "foo"
^
然而,这很好:
class MyClass extends MyTrait {
def apply[String](input:()=>String) = new String("foo")
}
那么在什么情况下scalac实际上知道需要进行转换以及在什么情况下不进行转换?
此外,即使我写出了java.lang.String类型的整个路径
class MyClass extends MyTrait {
def apply[java.lang.String](input:()=>java.lang.String) = new java.lang.String("foo")
}
它引发了另一个错误:
Error:(25, 21) ']' expected but '.' found.
def apply[java.lang.String](input:()=>java.lang.String) = new java.lang.String("foo")
^
如果我想通过直接模板化java.lang.String以后一种方式实现它,我将如何去做呢?
答案 0 :(得分:3)
此
class MyClass extends MyTrait {
def apply[String](input:()=>String) = new String("foo")
}
不是很好。它导致class type required but String found
。这里的问题是,当您使用参数化方法扩展类时,您不会声明类型参数是什么。您在使用该方法时声明它。
让我们改写:
class MyClass extends MyTrait {
def apply[String](input:()=>String) = input()
}
现在观察:
scala> (new MyClass).apply[String](() => "foo")
res0: String = foo
scala> (new MyClass).apply[Int](() => 5)
res1: Int = 5
这是有效的,因为当你宣布这个时:
def apply[String](input:()=>String) = input()
String
是参数的名称。如果您在上面写了T
,Xyzzy
或ManISuckAtTypeParameters
而不是String
,那将是完全相同的。您说您将获得一个类型参数,您将命名类型参数String
,并且这是返回函数的值,并且覆盖apply
方法。
当我致电apply[Int](() => 5)
时,Scala会在String
的定义中替换 Int
。