如何将“字符串”作为“可迭代[E]”



我正在使用 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].

此外,即使存在从StringIterable[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 中,有用于StringArray[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。

相关内容

  • 没有找到相关文章

最新更新