1

次の 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

が存在すると、 andから へstringToNodeの暗黙的な変換が何らかの形でブロックされるようです。なんで?そして、そのようなものを変更する方法はありますが、引数を必要とする関数を呼び出すときにまだ使用されていますか?str1str2WrappedStringstringToNodezipstringToNodeNodeString

4

2 に答える 2

6

ここにはあいまいな暗黙があります。StringOps と xml.Node の両方に zip メソッドがあるため、暗黙的な変換があいまいで解決できません。より良いエラーメッセージが表示されない理由がわかりません。

これをバックアップするためのリンクがいくつかあります: http://www.scala-lang.org/api/current/index.html#scala.collection.immutable.StringOps および http://www.scala-lang.org/api /current/index.html#scala.xml.Node

編集: それは、WrappedString ではなく、StringOps であり、リンクを変更しまし:) .

この場合、暗黙の使用は避けます。同じ名前のメソッドを提供する 2 つの異なる暗黙的な変換が必要です ( zip)。これは不可能だと思います。また、xml.Text をインポートするとText(str)、誰にでも十分簡潔に変換できます。この暗黙的な xml.Node への変換が必要な場合は、暗黙的な定義をオブジェクトにパックし、コードを読みやすくするために必要な場所にのみインポートし、場合によっては、必要な場所での競合を回避します。ジップストリング。しかし、基本的には、便利な変換を行うためだけに暗黙を使用することは避けます。

于 2013-03-05T19:25:22.633 に答える
3

@Felixが書いたように、使用したような類似のデータ型間の暗黙的な変換を定義することは一般的に悪い考えです。それを行うと、型システムが弱まり、遭遇したようなあいまいさが生じ、分析とデバッグが非常に困難な非常に不明確な (「魔法の」) コードが生成される可能性があります。

Scala での暗黙的な変換は、ラップされた型の API を強化するために、軽量で有効期間が短いラッパーを定義するために主に使用されます。Stringに変換する暗黙の変換は、WrappedStringそのカテゴリに分類されます。

Twitter のEffective Scalaには、この問題に関するセクションがあります。

于 2013-03-05T19:42:05.320 に答える