【问题标题】:Option method signature, function already defined in this scope选项方法签名,已在此范围内定义的函数
【发布时间】:2014-08-01 22:16:08
【问题描述】:
def createFloatBuffer(data: Option[Quaternion]*): Option[FloatBuffer] = data match {
  ...
}

def createFloatBuffer(data: Option[Vector3f]*): Option[FloatBuffer] = data match {
  ...
}

由于两个方法具有相同的方法签名,此代码将无法编译。 None 类型不知道调用哪个方法。

我可以重命名方法,但是我想在我的代码中使用这种重载样式。

【问题讨论】:

    标签: scala overloading method-signature


    【解决方案1】:

    类型擦除后这两个方法变成了createFloatBuffer(data: Option),所有类型信息都丢失了,在运行时不可用。

    作为一种解决方法,我建议您使用 TypeClass 模式。

    case class Quaternion(v: Int)
    case class Vector3f(v: Int)
    
    case class FloatBuffer(v: Int)
    
    sealed trait FloatBufferBuilder[T] {
      def createFloatBuffer(data: Option[T]): Option[FloatBuffer]
    }
    
    implicit object QuaternionFloatBufferBuilder extends FloatBufferBuilder[Quaternion] {
      def createFloatBuffer(data: Option[Quaternion]) = data.map(d => FloatBuffer(d.v))
    }
    
    implicit object Vector3fFloatBufferBuilder extends FloatBufferBuilder[Vector3f] {
      def createFloatBuffer(data: Option[Vector3f]) = data.map(d => FloatBuffer(d.v))
    }
    
    def createFloatBuffer[T : FloatBufferBuilder](data: Option[T]): Option[FloatBuffer] =
      implicitly[FloatBufferBuilder[T]].createFloatBuffer(data)
    
    
    println(createFloatBuffer(Some(Quaternion(1))))
    println(createFloatBuffer(Some(Vector3f(1))))
    

    磁铁图案也可能对您感兴趣:http://spray.io/blog/2012-12-13-the-magnet-pattern/

    【讨论】:

    • 这是一个非常有趣的解决方案,我认为最好的解决方案是避免将 Option 类型赋予方法,而是在调用方法之前将它们匹配。
    【解决方案2】:

    这是以下用例:

    scala> object X { def f(is: Int*) = 42 ; def f(ds: Double*) = 43 }
    <console>:10: error: double definition:
    def f(is: Int*): Int at line 10 and
    def f(ds: Double*): Int at line 10
    have same type after erasure: (is: Seq)Int
           object X { def f(is: Int*) = 42 ; def f(ds: Double*) = 43 }
                                                 ^
    
    scala> object X { def f(is: Int*) = 42 ; def f(ds: Double*)(implicit dummy: DummyImplicit) = 43 }
    defined object X
    
    scala> X f 1
    res2: Int = 42
    
    scala> X f 1.0
    res3: Int = 43
    

    【讨论】:

    • 你能补充一些关于如何解决这个问题的解释吗?
    • @Paul 哪个问题?第二个参数列表消除了运行时信号的歧义,X f (Seq.empty: _*) 选择第一个(如果需要的话),与 OP 中的 f(None) 问题相同。
    • 我不明白第二个参数列表如何消除运行时信号的歧义。也许我太密集了。
    • @Paul 我找不到规范的 SO 答案,但 stackoverflow.com/a/5736428/1296806。我希望很清楚 (Seq)Int 与 (Seq, Dummy)Int 不同。
    • 是的,这感觉更像是一种 hack,比如说我想用一个额外的类型重载方法,我必须创建一个新的虚拟对象。
    猜你喜欢
    • 2018-10-18
    • 2011-08-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-29
    • 1970-01-01
    • 2018-05-29
    • 1970-01-01
    相关资源
    最近更新 更多