scala隐式参数类型推断

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 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 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)
 }
}

谢谢你的回答!谢谢你的回答!谢谢你的回答!谢谢你的回答!