这是Oderdki教授的名为Rational的示例类,简化为强调:
class Rational(n: Int, d: Int) { def + (that: Rational): Rational = new Rational(this.numer * that.denom + that.numer * this.denom, this.denom * that.denom) def + (that: Int): Rational = new Rational(this.numer + that * this.denom, this.denom)
// implicit def IntToRational(a:Int)= new Rational(a)}
它不适用于表达式:
1 + new Rational(1, 2)
除非我取消注释隐式函数intToRational,它允许Scala自动转换l.h.s.到理性。 我的问题是:如果我必须定义一个转换函数来处理Int在lhs上的时候,为什么我必须定义一个在rhs上出现时需要Ints的方法?
以另一种方式提出问题,为什么Scala编译器不能将Int参数转换为Rational,所以我的第一个'+'定义(它接受一个Rational参数)适用于两者案件?
在我看来,Scala是一种如此聪明的语言,可能有一种方法可以声明一个类在其方法中是“可交换的”,因此编译器可以自由地进行这样的替换。然后,表达式:
Rational(1, 2) + 1
和
1 + Rational(1, 2)
两者都以相同的方式处理,并采用相同的方法。
我认为这是难以回答的问题之一,因为根据您的要求,答案要么非常明显,要么非常微妙。我认为这是一个值得解决的问题。顺便说一句,我喜欢Oderski教授在Coursera上课的课程!
答案 0 :(得分:2)
可以在双方使用Implicits,但是以效率为代价:添加Int
是一种更简单的操作。
通常你会像这样关心基本数学的效率。
正因为如此,你通常不会为LHS编写intToRational
,而是
implicit class IntRationalOps(val i: Int) extends AnyVal {
def +(r: Rational) = r + i
}
如果效率不是那么重要且可以始终执行转换(对于数学或其他事情),则隐式可以提供帮助。 (如果在任何地方转换都不是一个好主意,仍然可以使用IntRationalOps
方法。)