为什么以下内容无法编译
for {
s <- List.empty[String]
regex <- List.empty[scala.util.matching.Regex]
regex(ss) = s
if ss == "foo"
} yield s
但删除了if
for {
s <- List.empty[String]
regex <- List.empty[scala.util.matching.Regex]
regex(ss) = s
} yield s
或重新排列for comprehension中两个列表的顺序
for {
regex <- List.empty[scala.util.matching.Regex]
s <- List.empty[String]
regex(ss) = s
if ss == "foo"
} yield s
编译?
Scalafiddle:http://scalafiddle.net/console/2519ff98d434cb522589f54a9c5fcf55
答案 0 :(得分:2)
您可以使用以下命令查看翻译的for-comprehension:
scalac -Xprint:all <file>.scala
在您的第一个示例中,生成的代码如下所示(我稍微清理了输出):
List.empty[String]
.flatMap(((s) =>
List.empty[scala.util.matching.Regex]
.map(regex => {
private[this] val x$2 =
s match {
case (x$1@regex((ss@_))) => scala.Tuple2(x$1, ss)
};
val x$1 = x$2._1;
val ss = x$2._2;
scala.Tuple2(regex, x$1)
}).withFilter((x$3 => x$3 match {
case scala.Tuple2((regex@_), regex((ss@_))) => ss.$eq$eq("foo")
})).map(((x$4) => x$4 match {
case scala.Tuple2((regex@_), regex((ss@_))) => s
})))
)
问题似乎是withFilter
子句在regex(ss)
语句中直接使用表达式case
,但在那里没有定义值regex
。我不确定这是否可以被视为语言规范或编译器中的缺陷。错误信息当然不是很有帮助。
您可以阅读Scala language specification的第6.19章中的详细信息。
答案 1 :(得分:-2)
这可能会对你有帮助。
import scala.util.matching.Regex
import scala.util.control.Exception._
for {
s <- List.empty[String]
regex <- List.empty[scala.util.matching.Regex]
ss <- extract(regex, s)
if ss == "foo"
} yield s
def extract(regex: Regex, s: String): Option[String] = allCatch.opt {
val regex(ss) = s
ss
}