2012-10-04 311 views
8

我不明白的明顯矛盾的行爲我看到下面的代碼(斯卡拉2.9):斯卡拉多個隱式轉換?

class Pimp1(val x : Double) { 
    def pluss(that : Pimp1) = x + that.x 
    def <(that : Pimp1) = x < that.x 
} 

object Pimp1 { 
implicit def d2pimp(d : Double) = new Pimp1(d) 
implicit def d2pimp(od : Option[Double]) = new Pimp1(od.get) 
} 

object Scratch2 extends App { 
    import Pimp1._ 

    5.0.pluss(Some(5.0)) 
    5.0 < Some(5.0) 
} 

線「5.0.pluss(一些(5.0))」編譯,但行之後

重載方法值<與替代:(X:雙)布爾(X:浮點型)布爾(X:長)的布爾(X:智力)布爾(X它不與下面的錯誤消息編譯: Char)布爾值(x:Short)布爾值(x:Byte)布爾值不能應用於(某些[Double])

如果我添加明確<運營商的皮條客類,帶有一個選項[雙]:

def <(that : Option[Double]) = x < that.get 

一切編譯罰款。

現在,我明白了Scala的隱式轉換規則的方式,這是非常合情合理的:

  1. 編譯器明白,有沒有「<」雙接受選項[雙]
  2. 它認爲運營商隱式轉換爲Pimp1。
  3. 如果Pimp1有一個合適的操作符,它將起作用,否則它會生成一個錯誤。
  4. 重要的是,這表明編譯器確實而不是考慮應用從Option [Double]到Pimp的第二個(可用的)隱式轉換。

這就是我期望的事情。

然而,這似乎是第一個例子,在相互矛盾:

  1. 編譯器看到的是有雙沒有pluss方法。
  2. 編譯器嘗試將隱式轉換爲Pimp,後者確實有這種方法。
  3. 但是,爲了讓操作員工作,編譯器必須對參數應用第二個隱式轉換,將其轉換爲Pimp。

根據上面的邏輯,這不應該編譯,但它確實。隱式轉換規則是否以不同方式處理不存在的方法和非匹配方法?

+0

這很有趣,因爲如果你反轉它,它的工作原理:一些(5.0)<5.0 – Noah

回答

5

這對我有意義。第一個,這個作品是這樣的:

Does Double有一個pluss方法嗎?不,我們是否可以將它隱式轉換爲某種東西?是。好的,現在我想要應用pluss方法。它是否需要一個選項?我可以將選項隱含地轉換爲它需要的東西嗎?是。

第二個是這樣的:

有雙重有<方法?是。它是否需要一個選項?不,我可以隱式地將Option轉換爲<確實需要的東西嗎?沒有。

+0

正確。 scala編譯器不會嘗試爲已經具有所需方法的對象找到隱式轉換。選項沒有比較,所以一些(5.0)<0的作品。 –