Scala 为什么可以';t隐式转换可用于减少需要定义的方法的数量?

Scala 为什么可以';t隐式转换可用于减少需要定义的方法的数量?,scala,implicit-conversion,Scala,Implicit Conversion,这是Oderdki教授的示例课程,名为Rational,为强调简化: //隐式定义整数(a:Int)=新的有理数(a)} 它对表达式不起作用: 除非我取消注释隐式函数intToRational,它允许Scala自动将l.h.s.转换为Rational。我的问题是:如果我必须定义一个转换函数来处理l.h.s上的Int,为什么我必须定义一个在r.h.s上发生Int时接受Int的方法 换一种方式来说,为什么Scala编译器不能将Int参数转换为有理数,这样我的第一个“+”定义(使用有理数参数)就可以同

这是Oderdki教授的示例课程,名为Rational,为强调简化:

//隐式定义整数(a:Int)=新的有理数(a)}

它对表达式不起作用:

除非我取消注释隐式函数intToRational,它允许Scala自动将l.h.s.转换为Rational。我的问题是:如果我必须定义一个转换函数来处理l.h.s上的Int,为什么我必须定义一个在r.h.s上发生Int时接受Int的方法

换一种方式来说,为什么Scala编译器不能将Int参数转换为有理数,这样我的第一个“+”定义(使用有理数参数)就可以同时适用于两种情况

在我看来,Scala是一种非常聪明的语言,有一种方法可以在它的方法中声明一个类是“可交换的”,这样编译器就可以自由地进行这种替换。然后,表达:

两者的处理方式和方法都相同


我认为这是一个很难回答的问题,因为取决于你问谁,答案要么非常明显,要么非常微妙。我认为这是一个值得探讨的问题。顺便说一句,我喜欢奥德斯基教授的课程

隐式可以在双方都使用,但要以效率为代价:添加
Int
是一个更简单的操作

通常你关心的是这样的基础数学的效率

因此,您通常不会为LHS编写
intToRational
,而是

implicit class IntRationalOps(val i: Int) extends AnyVal {
  def +(r: Rational) = r + i
}

在效率不太重要的情况下,总是执行转换(对于数学或其他事情)是可以的,隐式转换可以有所帮助。(在各地转换不是一个好主意的情况下,仍然可以使用
intralops
方法。)

一个大问题是Scala操作符是多态的(并且本机实现为单个分派方法)-这不幸地打开了一个蠕虫的罐子。隐式实际上保持了基本操作的“显式”和一致性。谢谢,雷克斯!我很感激知道如何解决效率问题,但我也很好奇,如果我不关心效率的话,这个问题怎么解决。如果我只是想让两个表达式(即Int+Rational,Rational+Int)由同一个方法处理,会怎么样?你暗示“双方都可以使用隐式”。那么,你会怎么做呢?@user326503-只要去掉
+(that:Int)
方法,转换就会从另一个方法的
Int
生成一个
Rational
。你知道,雷克斯,这是我尝试的第一件事,(事实上是这篇文章的全部原因),但它不起作用。工作表会显示错误消息,如:类型不匹配;发现:Int(1)required:chap6.Rational有人知道它为什么不工作吗@user326503-您需要隐式表达式,它可以在某个地方找到。把它放在一个同伴对象中,或者放在类之外。(例如,
对象理性{implicit def intToRational…}
1 + new Rational(1, 2)
Rational(1, 2) + 1
1 + Rational(1, 2)
implicit class IntRationalOps(val i: Int) extends AnyVal {
  def +(r: Rational) = r + i
}