簡體   English   中英

Scala中的隱式沖突

[英]Collision of implicits in Scala

以下Scala代碼可正常運行:

val str1 = "hallo"
val str2 = "huhu"
val zipped: IndexedSeq[(Char, Char)] = str1.zip(str2)

但是,如果我導入隱式方法

implicit def stringToNode(str: String): xml.Node = new xml.Text(str)

然后Scala(2.10)編譯器顯示錯誤: value zip is not a member of String

看來stringToNode的存在以某種方式阻止了str1str2WrappedString的隱式轉換。 為什么? 並且有一種方法可以修改stringToNode ,使zip起作用,但是當我調用需要帶有StringNode參數的函數時仍使用stringToNode嗎?

您在這里有含糊的隱式。 StringOps和xml.Node都具有zip方法,因此隱式轉換是模棱兩可的,無法解決。 我不知道為什么它沒有給出更好的錯誤消息。

以下是一些支持備份的鏈接: http : //www.scala-lang.org/api/current/index.html#scala.collection.immutable.StringOpshttp://www.scala-lang.org/api /current/index.html#scala.xml.Node

編輯 :是StringOps,而不是WrappedString,更改了鏈接:)看一下Predef: http : //www.scala-lang.org/api/current/index.html#scala.Predef $在Scala中查看預定義的隱式。

在這種情況下,我將避免使用隱式。 您需要2個不同的隱式轉換,它們都提供相同名稱的方法( zip )。 我認為這是不可能的。 另外,如果導入xml.Text,則可以僅使用Text(str)進行轉換,這對於任何人都應該足夠簡潔。 如果您必須將此隱式轉換為xml.Node,我會將隱式def打包到一個對象中,然后僅在需要它的地方將其導入,以使代碼可讀,並盡可能避免在您也需要沖突的地方進行導入郵編。 但基本上,我會避免使用隱式函數只是為了進行方便的轉換。

就像@Felix所寫的一樣,在類似的數據類型之間定義隱式轉換通常是個壞主意,就像您所使用的那樣。 這樣做會削弱類型系統,導致像您遇到的模棱兩可,並且可能會產生非常不清楚(“魔術”)的代碼,這很難分析和調試。

Scala中的隱式轉換通常用於定義輕量級,短暫的包裝器,以豐富包裝類型的API。 String轉換為WrappedString隱式轉換屬於該類別。

Twitter的有效Scala中有關於此問題的部分。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM