scala - 在 Scala 中使用方法名称 "x"和隐式转换

标签 scala compilation implicit-conversion

假设我想通过提供这样的隐式转换来添加一个计算两个 3 元组的向量积的工具:

import scala.math.Numeric.Implicits._

case class Vector3[T : Numeric](a : T, b : T, c : T) {
    def x(v : Vector3[T]) = (b*v.c - c*v.b, c*v.a - a*v.c, a*v.b - b*v.a)
}

implicit def toVector[T : Numeric](p : (T,T,T)) = Vector3(p._1, p._2, p._3)

我希望以下代码可以编译:
       (1,0,0) x (0,1,0) // does not compile

但是,它会产生一个错误,即“x”不是 (Int, Int, Int) 的成员。
手动创建包装类的实例:
Vector3(1,0,0) x (0,1,0) // compiles

如果我使用另一个方法名称而不是“x”,例如“y”,则隐式转换也可以:
       (1,0,0) y (0,1,0) // compiles
Vector3(1,0,0) y (0,1,0) // compiles

“x”有什么特别之处?以及它如何干扰隐式转换机制?

最佳答案

.x 有什么问题| ?我们去问问吧:

scala> (1,2,3).x
<console>:23: error: type mismatch;
 found   : (Int, Int, Int)
 required: ?{def x: ?}
Note that implicit conversions are not applicable
because they are ambiguous:
 both method tuple3ToZippedOps in object Predef of type
   [T1, T2, T3](x: (T1, T2, T3))runtime.Tuple3Zipped.Ops[T1,T2,T3]
 and method toVector of type
   [T](p: (T, T, T))(implicit evidence$1: Numeric[T])Vector3[T]
 are possible conversion functions from (Int, Int, Int) to ?{def x: ?}

所以你看到了问题:x在另一个转换中用作基础元组的名称。这是来自runtime.Tuple3Zipped.Ops :
final class Ops[T1, T2, T3](val x: (T1, T2, T3)) extends AnyVal

这可以说是一个错误。 x是一个讨厌的参数,习惯上称它为reprunderlying ,并且在 2.11 中可以将其设为私有(private),以免打扰任何人。

关于scala - 在 Scala 中使用方法名称 "x"和隐式转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28776541/

相关文章:

伴随对象中的Scala隐式Numeric [T]

c# - 嵌套隐式运算符

scala - 是否可以仅通过 Maven 使用 Scala-Play 生态系统?如何?

java - 找不到速度模板资源

linux - 为什么 cmake 在我的构建目录中创建 'source' 目录?

c - 在编译中设置头文件路径?

scala - Scala隐式类转换的作用域

scala - 如何在scala curry函数中绑定(bind)第二个参数?

scala - AWS Glue Spark 作业 - 使用 CatalogSource 时如何对 S3 输入文件进行分组?

java - 寻找正确的 Java 指南