通过Scala中的隐式函数调用函数

时间:2017-07-18 10:21:12

标签: scala implicit

在Scala中,如果我有一个名为Vector2D的类,我想为它做一些隐式转换。目前,我已将此功能放在Vector2Dimplicit def fromFloatTuple(tuple: (Float, Float)): Vector2D = new Vector2D(tuple._1, tuple._2)

我可以成功完成以下val x: Vector2D = (1f, 1f)。但是,我不能做类似的事情:val x: Float = (1f, 1f).length()(显然长度是为Vector2D定义的)。为什么这不起作用,我希望它转换为类似val x: Float = fromFloatTuple((1f, 1f)).length()的东西,但事实并非如此。如何在Scala中获得此效果?

现在我想起来了,我怎么能让这个函数接受其他数值类型而不为所有数值类型的每个组合创建一个函数(不是2D矢量的问题,而是4D矢量的非常不洁)

2 个答案:

答案 0 :(得分:1)

当您有目标或源类型Vector2D时,编译器会查找Vector2D的伴随对象;在val x: Float = (1f, 1f).length()它没有。寻找隐式转换的所有可能类型会大大减慢编译速度,而Scala编译器已经很慢(虽然在改进)。

您需要通过导入fromFloatTuple进入范围:

import your.package.Vector2D._ // or just fromFloatTuple instead of _

答案 1 :(得分:-1)

This is exactly how it is supposed to work

import scala.language.implicitConversions

object Test {
  class Vector2D(x: Float, y: Float) { def length(): Float = x + y }

  implicit def fromFloatTuple(tuple: (Float, Float)): Vector2D = Vector2D(tuple._1, tuple._2)

  val x: Float = (1f, 1f).length()

对于更通用的情况,您可能需要查看scala.math.Numeric

  case class Vector4D[N](a: N, b: N, c: N, d: N)(implicit n: Numeric[N]) {
    import n._

    def length(): N = a + b + c + d
  }

  implicit def c2V4D[N: Numeric](tup: (N, N, N, N)): Vector4D[N] = new Vector4D(tup._1, tup._2, tup._3, tup._4)

  println(Vector4D(1,2,3,4).length())
  println(Vector4D(1,2,3,4.5).length())
  println((1,2,3,4).length())
}