我正在尝试创建从任何类型(例如,Int)到String ...
的隐式转换对String的隐式转换意味着RichString方法(如反向)不可用。
implicit def intToString(i: Int) = String.valueOf(i)
100.toCharArray // => Array[Char] = Array(1, 0, 0)
100.reverse // => error: value reverse is not a member of Int
100.length // => 3
隐式转换为RichString意味着String方法(如toCharArray)不可用
implicit def intToRichString(i: Int) = new RichString(String.valueOf(i))
100.reverse // => "001"
100.toCharArray // => error: value toCharArray is not a member of Int
100.length // => 3
使用两个隐式转换意味着重复的方法(如长度)不明确。
implicit def intToString(i: Int) = String.valueOf(i)
implicit def intToRichString(i: Int) = new RichString(String.valueOf(i))
100.toCharArray // => Array[Char] = Array(1, 0, 0)
100.reverse // => "001"
100.length // => both method intToString in object $iw of type
// (Int)java.lang.String and method intToRichString in object
// $iw of type (Int)scala.runtime.RichString are possible
// conversion functions from Int to ?{val length: ?}
那么,是否可以隐式转换为String并仍然支持所有String和RichString方法?
答案 0 :(得分:5)
我没有解决方案,但会在你的RichString
隐含之后注释intToString
方法不可用的原因是Scala不链接隐式调用(参见21.2“隐含规则”)在 Scala中编程)。
如果您引入中间版String
,Scala会将隐含权转换为RichString
(隐式在Predef.scala
中定义)。
如,
$ scala
Welcome to Scala version 2.7.5.final [...].
Type in expressions to have them evaluated.
Type :help for more information.
scala> implicit def intToString(i: Int) = String.valueOf(i)
intToString: (Int)java.lang.String
scala> val i = 100
i: Int = 100
scala> val s: String = i
s: String = 100
scala> s.reverse
res1: scala.runtime.RichString = 001
答案 1 :(得分:5)
从Scala 2.8开始,这已经得到了改进。根据{{3}}(§避免歧义):
以前,最具体的重载方法或隐式转换 将仅基于方法的参数类型来选择。有一个 附加条款,说最具体的方法不可能 在任何其他替代方案的适当超类中定义。这个 Scala 2.8中的方案已由以下更自由的方案取代: 比较两种不同适用的超载替代方案 方法或隐含的方法,每个方法获得一个点以获得更多 特定的论点,以及另一个适当的定义点 子类。如果获得更多的数字,另一种选择“赢”另一个 这两个比较中的要点。 这尤其意味着如果 替代品具有相同的参数类型,即在a中定义的参数类型 子类获胜。
有关示例,请参阅this paper(§6.5)。
答案 2 :(得分:2)
我看到的唯一选择是创建一个新的String Wrapper类MyString,让它调用你想要在不明确的情况下调用的任何方法。然后,您可以定义MyString的隐式转换以及从MyString到String和RichString的两个隐式转换,以防您需要将其传递给库函数。
答案 3 :(得分:2)
要么制作一个巨大的代理类,要么吸收它并要求客户端消除它的歧义:
100.asInstanceOf [字符串]。长度
答案 4 :(得分:2)
接受的解决方案(由Mitch Blevins发布)永远不会奏效:使用Int
向String
转发asInstanceOf
将始终失败。
您的问题的一个解决方案是将任何String-convertible类型的转换添加到RichString
(或者更确切地说,添加到StringOps
,因为它现在已命名):
implicit def stringLikeToRichString[T](x: T)(implicit conv: T => String) = new collection.immutable.StringOps(conv(x))
然后像以前一样将转换定义为字符串:
scala> implicit def intToString(i: Int) = String.valueOf(i)
warning: there was one feature warning; re-run with -feature for details
intToString: (i: Int)String
scala> 100.toCharArray
res0: Array[Char] = Array(1, 0, 0)
scala> 100.reverse
res1: String = 001
scala> 100.length
res2: Int = 3
答案 5 :(得分:1)
我很困惑:你不能在任何类型上使用.toString
,因此无需隐式转换吗?