问题重写 scala 方法 post 升级到 scala 2.12(从 2.11)

Problem rewriting scala method post upgrade to scala 2.12 (from 2.11)

我的项目中有以下小而复杂的方法:

private def indent ( s : String )
  = s.lines.toStream match {
    case h +: t =>
      ( ("- " + h) +: t.map{"| " + _} ) mkString "\n"
    case _ => "- "
  }

将我的项目从 Scala 2.11 升级到 2.12 后,它将不再编译。错误:

CaseClassString.scala:14: value toStream is not a member of java.util.stream.Stream[String]

我试过这样重写:

private def indent ( s : String )
  = Stream(s.lines) match {
    case h +: t =>
      ( ("- " + h) +: t.map{"| " + _} ) mkString "\n"
    case _ => "- "
  }

但它不起作用。

在以下项目中发现了该方法: https://github.com/nikita-volkov/sext

该函数将转换如下字符串:

metricResult: column: value: city
function: density
value: metricValue: 0.1

至:

- metricResult: column: value: city
| - function: density
| - value: metricValue: 0.1

有人对如何为 Scala 2.12 重写此方法有其他想法吗?

我怀疑您还将 JVM 从 Java 8 升级到 Java 11(或者正在使用 Java 8 上 运行 上写入的代码 Java 11). Java 11 向 String 添加了一个 lines 方法,结果是 java.util.Stream[String]。在 Java 8 上,String 没有 lines 方法,这意味着 Scala 编译器可以将 String 隐式转换为 scala.collection.immutable.StringOps,后者具有 lines 结果类型为 Iterator[String].

的方法

这里的技巧是要明确表示你想使用 StringOps.lines 而不是 String.lines,所以类似于

val lines = (s: scala.collection.immutable.StringOps).lines
lines.toStream match {
  // etc.
}

看来您不仅升级了Scala,还升级了Java版本。如果您只查看 Java 和 Scala 的与 String 相关的更改,则该错误很容易理解。

import scala.collection.immutable.StringOps

def indent(s : String): String =
  (s: StringOps).lines.toStream match {
    case h +: t =>
      ( ("- " + h) +: t.map{"| " + _} ) mkString "\n"
    case _ => "- "
  }

或者,如果您正在使用 Java 11 并且真的不需要 Stream,那么,

def indent(s : String): String =
  s.lines.toArray.toList match {
  case h :: t =>
    val indented = ("- " + h) :: t.map{"| " + _}
    indented.mkString("\n")
  case _ => "- "
}

与安德烈的解决方案非常相似,但有效:

def indent(s: String) = s.linesIterator.mkString("- ", "\n| - ", "")

代码 运行 在 scatie