我正在使用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)value splitOn不是String的成员 可能的原因:在'value splitOn'之前可能缺少分号? .splitOn(s => Character.isWhitespace(s.head))
......当我试着这个......
line: String =>
val Some((identifier: String, patternn: String)) =
line
// take the identifier
.splitOn(s => Character.isWhitespace(s.head))
答案 0 :(得分:5)
那是因为Iterable[E]
是一个Scala特征,并且是一个相对“最近”的发明,而java.lang.String
是从1.0版开始就存在的基本Java数据类型。从1995年开始。显然,java.lang.String
没有实现Iterable[E]
。
此外,即使存在从String
到Iterable[E]
的隐式转换,Scala也永远不会尝试对单个表达式进行多次隐式转换。
如果您想要pimp 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] = ???
}
这会给你几乎相同的功能,但它不需要不受控制的隐式转换爆炸。
答案 1 :(得分:0)
String
(以及Array[T]
)继承自Java,因此不会扩展Scala的Iterable
。但是在Scala中,String
和Array[T]
包含了对IndexedSeq
及Iterable
扩展的对象的隐式包装。
请求隐式转换参数的原始接口是view bound:
implicit class PStream[E, T <% Iterable[E]](stream: T) {
/* ... */
}
现在已弃用,但您可以将隐式转换请求为隐式参数:
implicit class PStream[E, T](stream: T)(implicit toIterable: T => Iterable[E]) {
/* ... */
}
此代码将支持普通Iterable
以及String
和Array
s。