2015-11-08 48 views
0

我試過下面的this答案,但它沒有幫助。這是我的實現。覆蓋String.toBoolean的隱式類

implicit class MyString(s: String) { 
    override def toBoolean = s.trim.toLowerCase match { 
    case "true" | "t" | "1" => true 
    case _ => false 
    } 
} 

而且我得到的錯誤是:

[error] found : s.type (with underlying type String) 
[error] required: ?{def toBoolean: ?} 
[error] Note that implicit conversions are not applicable because they are ambiguous: 
[error] both method augmentString in object Predef of type (x: String)scala.collection.immutable.StringOps 
[error] and method MyString in trait ImplicitsStartingWithS of type (s: String)foo.MyString 
[error] are possible conversion functions from s.type to ?{def toBoolean: ?} 
[error]   case Some(s) => s.toBoolean 
[error]       ^

我似乎無法找到什麼是錯的代碼。

回答

0

首先,請注意,隱式轉換無法在類型重寫方法轉化來自:如果這樣的方法存在,編譯器根本不會找隱!有一個叫做Scala-Virtualized的Scala的叉子,它允許這個(你可以定義一個方法infix_toBoolean(x: String)),但是我建議不要使用它來作爲一般用法:如果你不能沒有這個功能,請檢查它。

在這種情況下,正如@ moem的回答所說,toBoolean實際上並沒有在String上定義。 def augmentString = ???

class MyString(s: String) { 
    def toBoolean = s.trim.toLowerCase match { 
    case "true" | "t" | "1" => true 
    case _ => false 
    } 
} 

implicit def augmentString(s: String) = new MyString(s) 

當然,這失去了此提供的所有其他方法:作爲替代簡單地給出一個不同的名稱,以你的toBoolean,你也可以明確地定義別的東西與這個名字藏在一類augmentString也是隱含的,但您可以在MyString中提供它們(例如,通過擴展StringOps)。

1

除了toBoolean沒有覆蓋任何東西的事實,您的實現很好。但是,由於編譯器錯誤有助於表明,您的方法的名稱與Predef中自動導入的StringOps類中的toBoolean方法衝突。因此,可以應用多個隱式轉換,編譯器無法決定使用哪一個。這就是爲什麼錯誤表明存在歧義。解決方案是以不同的方式命名你的方法,所以以下應該工作。

implicit class MyString(s: String) { 
    def toBooleanAlt = s.trim.toLowerCase match { 
    case "true" | "t" | "1" => true 
    case _ => false 
    } 
}