我的代码如下:
type Occurrences = List[(Char, Int)]
def subtract(x: Occurrences, y: Occurrences): Occurrences = for {
(theChar, theInt) <- x
yMap = y.toMap
finalInt = theInt - yMap.getOrElse(theChar,0)
if finalInt != 0
} yield (theChar, finalInt)
我想知道yMap= y.toMap
是仅被评估一次还是多次..如果对它进行了多次评估,那么只评估一次的正确语法是什么?
答案 0 :(得分:3)
只需将ymap = y.toMap
部分从for
理解中删除。
def subtract(x: Occurrences, y: Occurrences): Occurrences = {
val yMap = y.toMap
for {
(theChar, theInt) <- x
finalInt = theInt - yMap.getOrElse(theChar, 0)
if finalInt != 0
} yield (theChar, finalInt)
}
Scala For Comprehensions只是一种语法糖。
例如,您的代码将由编译器转换为以下代码(不完全是以下代码,但概念是相同的):
def subtract(x: Occurrences, y: Occurrences): Occurrences = x map {
case (theChar, theInt) =>
def yMap = y.toMap
def finalInt = theInt - yMap.getOrElse(theChar, 0)
(theChar, finalInt)
} filter {
case (_, theInt) =>
theInt != 0
}
因此,map
部分中的任何表达式都将针对集合中的每个项目执行(在本例中为x
)。通过将y = y.toMap
部分移出for
块,代码将被转换为:
def subtract(x: Occurrences, y: Occurrences): Occurrences = {
def yMap = y.toMap
x map {
case (theChar, theInt) =>
def finalInt = theInt - yMap.getOrElse(theChar, 0)
(theChar, finalInt)
} filter {
case (_, theInt) =>
theInt != 0
}
}
这很可能是你真正想要的。
答案 1 :(得分:1)
对x
的每个元素进行一次评估; (theChar, theInt) <- x
下面的所有是。
如果您只想评估一次,请将其保留在循环每个元素的任何内容之外。例如,
def subtract(x: Occurrences, y: Occurrences): Occurrences = {
val yMap = y.toMap
for {
(theChar, theInt) <- x
finalInt = theInt - yMap.getOrElse(theChar,0)
if finalInt != 0
} yield (theChar, finalInt)
}
会做到这一点。