SBT对Scala类型感到困惑

时间:2018-12-11 21:58:49

标签: scala sbt

SBT引发以下错误:

value split is not a member of (String, String)
[error]       .filter(arg => arg.split(delimiter).length >= 2)

对于以下代码块:

implicit def argsToMap(args: Array[String]): Map[String, String] = {
val delimiter = "="
args
  .filter(arg => arg.split(delimiter).length >= 2)
  .map(arg => arg.split(delimiter)(0) -> arg.split(delimiter)(1))
  .toMap
}

有人可以解释这里发生了什么吗? 一些细节:

java version "1.8.0_191"
sbt version 1.2.7
scala version 2.11.8

我在命令行和intellij上都尝试过。我也尝试了Java 11和Scala 2.11.12,但无济于事。

我无法在另一台机器上复制它(虽然是不同的OS,SBT,IntelliJ等),并且我还可以写一个最小的失败案例:

value split is not a member of (String, String)
[error]     Array("a", "b").map(x => x.split("y"))

2 个答案:

答案 0 :(得分:3)

问题是filter方法是通过隐式添加到数组的。 调用args.filter(...)时,args通过ArrayOps隐式方法转换为Predef.refArrayOps

您正在定义从Array[String]Map[(String, String)]的隐式转换。 该隐式优先级比Predef.refArrayOps高,因此可以代替。

因此args被转换为Map[(String, String)]。该Map的filter方法应以(String, String) => Boolean类型的函数作为参数。

答案 1 :(得分:2)

我相信发生的事情是隐式方法被急切地调用了。也就是说,似乎Tuple2冒出来的是隐式函数将每个String转换为键/值对的结果。隐式函数是递归地调用自身。我最终在处理其他String s集合的其他代码导致堆栈溢出之后发现了这一点。