我正在使用 Scala 的implicit class
机制,无法java.lang.String
识别为Iterable[A]
。
implicit class PStream[E](stream: Iterable[E]) {
def splitOn(test: Iterable[E] => Boolean): Option[(Iterable[E], Iterable[E])] = {
???
}
}
仅根据上述定义,IntelliJ 和 SBT 声明......
错误:(31, 8( 值拆分不是字符串的成员 可能的原因:也许在"值拆分"之前缺少分号? .splitOn(s => Character.isWhitespace(s.head((
。当我尝试这个时...
line: String =>
val Some((identifier: String, patternn: String)) =
line
// take the identifier
.splitOn(s => Character.isWhitespace(s.head))
这是因为Iterable[E]
是Scala的一个特征,并且是一个相对"最近"的发明,而java.lang.String
是一个基本的Java数据类型,从1995年开始就已经存在1.0版本。显然,java.lang.String
没有实现Iterable[E]
.
此外,即使存在从String
到Iterable[E]
的隐式转换,Scala也不会在单个表达式上尝试超过一次的隐式转换。
如果你想皮条客String
,你必须String
作为单个参数传递给你的隐式类。编译器将拒绝构建多个隐式转换的疯狂塔,因为否则会使编译时间不可接受。
您可以尝试的是这样的内容:
implicit def toPStreamOps[X, E](x: X)(implicit iter: IsIterable[X, E])
: PStream[X, E] = ???
然后提供单独的
implicit object StringIsIterableChar
extends IsIterable[String, Char] {
def asIterable(s: String): Iterable[Char] = ???
}
这将为您提供几乎相同的功能,但它不需要不受控制的隐式转换爆炸。
String
(也是Array[T]
(是从Java继承而来的,因此不会扩展Scala的Iterable
。不过,在 Scala 中,有用于String
和Array[T]
的隐式包装器,这些包装器可以扩展到IndexedSeq
并相应地Iterable
的对象。
请求参数隐式转换的原始接口是视图绑定:
implicit class PStream[E, T <% Iterable[E]](stream: T) {
/* ... */
}
它现在已弃用,但您可以只请求隐式转换作为隐式参数:
implicit class PStream[E, T](stream: T)(implicit toIterable: T => Iterable[E]) {
/* ... */
}
此代码将支持正常的 Iterable
s,以及 String
s 和 Array
s。