scala隐式参数类型推断
在scala 2.10.4下运行以下脚本。我希望a.classOp的结果应该是MyPage。为什么什么都不是scala隐式参数类型推断,scala,Scala,在scala 2.10.4下运行以下脚本。我希望a.classOp的结果应该是MyPage。为什么什么都不是 scala> trait PageModel { | def classOp[T](implicit manifest: Manifest[T]) { | println("Class: " + manifest.runtimeClass.getName) | } | } defined trait PageModel scala> class MyPage ex
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 = MyPage@1f2f992
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 = MyPage@f7bf869
scala> a.classOp
Class: java.lang.Object
我想你是想在它的子类上参数化
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。我想你是想在它的子类上参数化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。当您定义此方法时,def classOp[T](…)
约束到什么?它本质上可以是任何内容,因此您正在请求类型T
的隐式清单,该类型可以是任何内容:隐式清单:清单[T]
如果查看scala.Predef
,可以看到以下声明:
val NoManifest = scala.reflect.NoManifest
其中NoManifest
是:
object NoManifest extends OptManifest[Nothing]
/** A `OptManifest[T]` is an optional [[scala.reflect.Manifest]].
* It is either a `Manifest` or the value `NoManifest`.
其中,OptManifest
是:
object NoManifest extends OptManifest[Nothing]
/** 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)
}
}
定义此方法时,
def classOp[T](…)
约束到什么?它本质上可以是任何内容,因此您正在请求类型T
的隐式清单,该类型可以是任何内容:隐式清单:清单[T]
如果查看scala.Predef
,可以看到以下声明:
val NoManifest = scala.reflect.NoManifest
其中NoManifest
是:
object NoManifest extends OptManifest[Nothing]
/** A `OptManifest[T]` is an optional [[scala.reflect.Manifest]].
* It is either a `Manifest` or the value `NoManifest`.
其中,OptManifest
是:
object NoManifest extends OptManifest[Nothing]
/** 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)
}
}
谢谢你的回答!谢谢你的回答!谢谢你的回答!谢谢你的回答!