【问题标题】:Scala error implementing abstract method with type parameterScala错误使用类型参数实现抽象方法
【发布时间】:2013-08-29 20:39:51
【问题描述】:

简而言之,这是可行的:

object Main {
  def main(args: Array[String]) {
    trait T1[T] {
      def f1(a: T): Double
    }

    val ea1 = new T1[List[String]] {
      def f1(a: List[String]): Double = a.length
    }
  }
}

但这不会编译:

object Main {
  def main(args: Array[String]) {
    trait T1 {
      def f1[T](a: T): Double
    }

    val ea1 = new T1 {
      def f1(a: List[String]): Double = a.length
    }
  }
}

object creation impossible, since method f1 in trait T1 of type [T](a: T)Double is not defined
    val ea1 = new T1 {
              ^

由于方法上的类型参数,似乎没有考虑该方法。

如何在不使用特征类型参数或特征抽象类型的情况下实现这一点?! 蒂亚!

【问题讨论】:

    标签: scala type-parameter abstract-methods


    【解决方案1】:

    您可能想要定义一个type T 来取消特征类型参数并完成与...相同的操作。

        trait T1 {
          type T
          def f1(a: T): Double
        }
    
        val ea1 = new T1 {
           type T = List[String]
           def f1(a: T): Double = a.length
        }                                            
    
        ea1.f1(List("1","2"))  
        // res0: Double = 2.0
    

    【讨论】:

    • 虽然这是一个很好的解决方案,但我已经说过我不想要特征类型参数,我希望推断函数中的 T 类型。在像这样的简单情况下,特征抽象类型就像普通的类类型参数一样工作......
    • 好吧,由于您的回答,我设法得到了我想要的东西,我会接受它......
    【解决方案2】:

    有一个“私人选项”-Yinfer-argument-types 可让您:

    scala> trait T { def f(i: Int) }
    defined trait T
    
    scala> new T { def f(i) = 2 * i }
    res1: T = $anon$1@7915e83
    

    您要求的选项相当于:

    scala> new T { def f() = 2 * i }
    

    除了类型参数而不是值参数。

    我不确定您的示例中的语义是什么。该方法有一个类型参数,但如果它不是我期望的类型,则抛出?

    编辑:也许你的意思是这样的:

    scala> trait T { def f[ @specialized(Int) A](a: A): A = ??? }
    defined trait T
    
    scala> new T { def f(i: Int) = 2*i }
    res0: T{def f(i: Int): Int} = $anon$1@50844aeb
    
    scala> res7 f 7
    warning: there were 1 feature warning(s); re-run with -feature for details
    res8: Int = 14
    

    专用方法上没有类型参数。

    更新:这可能是 SO 上第一次出现省略的 REPL 堆栈跟踪:

    scala> res7 f "hi!"
    warning: there were 1 feature warning(s); re-run with -feature for details
    scala.NotImplementedError: an implementation is missing
      at scala.Predef$.$qmark$qmark$qmark(Predef.scala:229)
      at $anon$1.f(<console>:9)
    

    【讨论】:

    • 不知道 -Yinfer-argument-types,谢谢!不幸的是,当我实例化特征时给出类型参数正是我想要避免的,考虑到我希望客户端在不提供类型参数的情况下实现该函数(然后使用视图边界进行方差/逆变)。在我看来,Scala 类型推断似乎太过分了……
    • @VincenzoMaggio 专业化是您想要的。我的问题是,如果不是您期望的类型,您会怎么做,答案是:调用另一种方法。至少,专业化是我理解你的问题的唯一方法。
    • 特化不只是针对原始类型吗?!
    • @VincenzoMaggio 是的,我在构思。您可以自己进行调度,无论是动态还是使用宏,从 f[A: TypeTag](a: A) 到任何可用的实现。
    猜你喜欢
    • 2023-03-22
    • 2021-02-02
    • 2013-07-10
    • 2021-12-29
    • 1970-01-01
    • 2018-08-01
    • 2015-06-29
    • 2023-03-10
    相关资源
    最近更新 更多