【问题标题】:Why does the use of typed variable make this code work为什么使用类型化变量会使这段代码工作
【发布时间】:2017-06-01 13:47:10
【问题描述】:

这行得通

trait SomeTrait {   
  type T   
 def write2( s: String): T 
}

case class C() extends SomeTrait {  
  type T = String   
  override  def write2(s:String): T = s }

但这不是

trait SomeTrait {  
  def write2[T]( s: String): T 
}

case class C() extends SomeTrait {   
 override  def write2(s: String): String =s }

根据我的推理,它们..看起来很相似。为什么编译器特别给出“方法不会覆盖任何东西”错误?有没有办法使这项工作?

【问题讨论】:

  • 请以不同的名称命名你的类型参数和你的基本特征,这样会更容易混淆。
  • ..已更新,谢谢

标签: scala


【解决方案1】:

如果你使用这个定义:

trait T {  
  def write2[T]( s: String): T 
}

考虑一些使用此特征的客户。例如:

def doSomething(t: T): Unit = {
  val s: String = t.write2[String]("hello")
  val n: Int = t.write2[Int]("world")
  val d: Double = t.write2[Double]("!")
  println(s + n.toString + d.toString)
}

我不知道 s、n 和 d 的值是什么,但从编译器的角度来看,理论上这将是该特征的完全有效用法。因此,为了真正覆盖 write2[T] 方法,您必须为 所有 可能的类型 T 提供有效行为。

比较一下:

trait T2 {   
  type T   
  def write2( s: String): T 
}

甚至:

trait T3[T] {
  def write2(s: String): T
}

那么当调用者使用它时:

def doSomething(t: T2): Unit = {
  val x = t.write2("hello") // always returns type t.T
}

def doSomething[T](t: T3[T]): Unit = {
  val x = t.write2("hello") // always returns type T
}

只有一种可能的类型可以返回,一旦您拥有该特征的特定实例。因此,要覆盖该方法,您只需覆盖该类型的行为。

【讨论】:

    【解决方案2】:

    你在第二个 sn-p 中的 trait 定义并不意味着它的实现必须有一个方法 write2 用于某些类型 T,但它必须有一个方法 write2 接受一个类型参数 @987654324 @。

    这意味着,如果你有一个值v: SomeTrait,你应该能够做到

    val stringed: String = v.method2[String]("foo")
    val inted: Int = v.method2[Int]("foo")
    

    【讨论】:

      【解决方案3】:

      这样编译:

      trait T {
           def write2[T]( s: String): T
       }
      
       case class C() extends T {
           override  def write2[T](s: String): T =s.asInstanceOf[T]
       }
      

      write2 返回一个 T,而不是一个 String(因此你的第二个覆盖不起作用的原因以及上面代码中丑陋演员的必要性)

      【讨论】:

      • 这可以编译,但完全没有用处。
      • @AlexeyRomanov 目标不是让它“有用”,而是解释为什么T 不是String 类型,OP 的覆盖不会编译
      猜你喜欢
      • 1970-01-01
      • 2016-12-18
      • 2014-05-29
      • 2021-08-10
      • 2019-08-18
      • 1970-01-01
      • 1970-01-01
      • 2015-07-20
      • 2019-06-06
      相关资源
      最近更新 更多