scala隐式参数类型推断
在scala 2.10.4下运行以下脚本。我期待a.classOp的结果应该是MyPage。为什么没有?scala隐式参数类型推断
scala> trait PageModel {
| def classOp[T](implicit manifest: Manifest[T]) {
| println("Class: " + manifest.runtimeClass.getName)
| }
| }
defined trait PageModel
scala> class MyPage extends PageModel
defined class MyPage
scala> val a = new MyPage
a: MyPage = [email protected]
scala> a.classOp
Class: scala.runtime.Nothing$
编辑:
我觉得我得到了答案。谢谢! 但是,在2.9.3上运行相同的代码给了我一个java.lang.Object是非常有趣的。它应该表现如何?我在2.9.3中也看到了NoManifest。
scala> trait PageModel{
| def classOp[T](implicit m: Manifest[T]) {
| println("Class: " + manifest[T].erasure.getName)
| }
| }
defined trait PageModel
scala> class MyPage extends PageModel
defined class MyPage
scala> val a = new MyPage
a: MyPage = [email protected]
scala> a.classOp
Class: java.lang.Object
当你定义这个方法def classOp[T](...)
什么是T
约束?它基本上可以是任何东西,所以你要求一个T
类型的隐式清单,它可以是任何东西:implicit manifest: Manifest[T]
。
如果您在scala.Predef
,您可以看到以下声明:
val NoManifest = scala.reflect.NoManifest
其中NoManifest
是:
object NoManifest extends OptManifest[Nothing]
在哪里OptManifest
是:
/** A `OptManifest[T]` is an optional [[scala.reflect.Manifest]].
* It is either a `Manifest` or the value `NoManifest`.
那么所有这转化为?
由于Nothing
是所有类型的亚型,并始终有一个Manifest[Nothing]
范围(Predef
总是在范围内)这将意味着在没有其他发现这个隐将被注入。
与此说,我同意Ryan和你大概的意思做:
trait PageModel[T] {
def classOp(implicit manifest: Manifest[T]) {
println("Class: " + manifest.runtimeClass.getName)
}
}
我想你的意思是参数上它的子类PageModel
,因为现在a.classOp
没有任何东西T
与这样编译器无二底式,Nothing
填补。
例如:
scala> a.classOp[String]
java.lang.String
我假设你希望得到的MyPage
类名。在这种情况下,你需要在它的子类型参数PageModel
:
trait PageModel[T] {
def classOp(implicit manifest: Manifest[T]) =
println("Class: " + manifest.runtimeClass.getName)
}
class MyPage extends PageModel[MyPage]
val a = new MyPage
a.classOp // prints "Class: $line11.$read$$iw$$iw$MyPageModel"
显然REPL classOp
外面会打印出更可读FQCN。
感谢您的回答! – 2014-12-02 21:04:27
感谢您的回答! – 2014-12-02 21:04:10