Scala:“隐式”和类型参数

| 我在理解以下现象时遇到​​了一些麻烦:
trait Trait[A] {
  def traitType: String
}

object Trait {
  implicit val stringTrait: Trait[String] = new Trait[String] {
    def traitType: String = \"string\"
  }

  implicit val intTrait: Trait[Int] = new Trait[Int] {
    def traitType: String = \"int\"
  }
}

class Media[A] {
  // works
  def mediaType(implicit t: Trait[A]): String = t.traitType
  // does not compile
  def mediaType: String = implicitly[Trait[A]].traitType
}

object Main {
  def main(args: Array[String]) {
    val a = new Media[String]
    val b = new Media[Int]

    println(a.mediaType)
    println(b.mediaType)
  }
}
在上面的代码片段中,我展示了mediaType方法的2种不同实现(在编译代码时,我将其中一种注释掉了)。但是隐式使用的版本无法编译?我收到以下错误消息:
impl.scala:19: error: could not find implicit value for parameter e: Trait[A]
  def mediaType: String = implicitly[Trait[A]].traitType
                                    ^
one error found
我确实知道没有可用的Trait [A]隐式值。我不明白为什么A不能解析为Media实例化的类型。我想我在这里对C ++模板的思考太多了,如果有人可以向我指出正确的方向,我将不胜感激。 问候, 雷乔     
已邀请:
编译器需要证据,证明
A
存在隐式
Trait
实例。在第一个“ 4”实现中,您声明此要求。但是在第二种实现中,从编译器的角度来看,没有这样的保证。因此,为了使它起作用,您应该请
Media
类的用户提供它。您可以通过上下文绑定来实现:
class Media[A : Trait] {
  def mediaType: String = implicitly[Trait[A]].traitType
}
这也可以更明确地写成:
class Media[A](implicit val evidence: Trait[A]) {
  def mediaType: String = implicitly[Trait[A]].traitType
}
因此,换句话说,默认构造函数需要隐式的
evidence
,并且如果没有提供(显式或隐式)它,用户将无法实例化
Media
类。     
如果要编译此版本:
def mediaType: String = implicitly[Trait[A]].traitType
那么需要传递“ 11”的隐式实例,例如创建新的“ 5”实例时。尝试按以下方法定义
Media
class Media[A](implicit private val t: Trait[A]) {
  def mediaType: String = t.traitType
}
使用上下文绑定的几乎等同的定义是:
class Media[A: Trait] {
  def mediaType: String = implicitly[Trait[A]].traitType
}
话虽如此,如果您想做的是保留有关参数化类型的类型参数的更多信息,则可能要使用ѭ16而不是您自己的机制。他们将在运行时为您提供有关ѭ3type的完整类型信息,包括if3ѭ本身是参数化类型时的信息:
scala> class Media[A](implicit val aManifest: Manifest[A])
defined class Media

scala> new Media[Int].aManifest
res0: Manifest[Int] = Int

scala> new Media[Seq[(Int, String)]].aManifest        
res1: Manifest[Seq[(Int, String)]] = scala.collection.Seq[scala.Tuple2[Int, java.lang.String]]
    

要回复问题请先登录注册