scala 中隱式轉換 implicit的應用

下面是一個Rational的類

class Rational(n: Int, d: Int) {

  require(d != 0)
  
  private val g = gcd(n.abs, d.abs)
  
 
  
  val numer: Int = n / g
  val denom: Int = d / g
  
  def this(n: Int) = this(n, 1)
  
  override def toString = numer + "/" + denom
  def add(that: Rational): Rational = 
    new Rational(
        numer * that.denom + that.numer * denom,
        denom * that.denom
    )
  
  def lessThan(that: Rational) =
    this.numer * that.denom < that.numer * this.denom
  
  def max(that: Rational) =
    if (this.lessThan(that)) that else this
    
  private def gcd(a: Int, b: Int): Int =
    if (b == 0) a else gcd(b, a%b)
    
  def + (that: Rational): Rational = 
    new Rational(
        numer * that.denom + that.numer * denom,
        denom * that.denom
    )
  
  def + (i: Int): Rational =
    new Rational(numer + i * denom, denom)
  
  def * (that: Rational): Rational =
    new Rational(
        numer * that.numer, denom * that.denom    
    )
  
  def * (i: Int): Rational =
    new Rational(numer * i, denom)
  
  def - (i: Int):Rational =
    new Rational(numer - i * denom, denom)
  
  def - (that: Rational): Rational =
    new Rational(
        numer * that.denom - that.numer * denom,
        denom * that.denom    
    )
  
  def / (that: Rational):Rational =
    new Rational(numer * that.denom, denom * that.numer)
  
  def / (i: Int): Rational =
    new Rational(numer, denom * i)
}

下面簡單的使用一下Rational類

object Test extends App{
  
   val x = new Rational(1,2)
   val y = new Rational(2,3)
 
<pre name="code" class="plain">  <span style="color:#009900;">println(y * 2)</span>

}


可以正常輸出結果:4/3

我們把輸出的改爲:

object Test extends App{
  
   val x = new Rational(1,2)
   val y = new Rational(2,3)
 
  println(2 * y)


}
會報如下,錯誤:

overloaded method value * with alternatives: (x: Double)Double <and> (x: Float)Float <and> (x: Long)Long <and> (x: Int)Int <and> (x: Char)Int <and> (x: Short)Int <and> (x: Byte)Int cannot be applied to (mytest.Rational)

原因是:

The problem here is that 2 * r is equivalent to 2.*(r), so it is a method
call on the number 2, which is an integer. But the Int class contains no
multiplication method that takes a Rational argument—it couldn’t because
class Rational is not a standard class in the Scala library.
However, there is another way to solve this problem in Scala: You can
create an implicit conversion that automatically converts integers to rational
numbers when needed. Try adding this line in the interpreter:


這個時候就需要隱式轉換

object Test extends App{
  
   val x = new Rational(1,2)
  val y = new Rational(2,3)
 
 implicit def intToRational(x: Int) = new Rational(x) //隱式轉換
  println(2 * y)


此時,就可以正常輸出了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章