来自foreach的短路功能

Nic*_*ick 9 functional-programming scala

我和我的同事对以下代码的行为感到有点困惑.

def a: String = {
  None.foreach(return "1")
  return "2"
}

def b: String = {
  None.foreach(x => return "1")
  return "2"
}
Run Code Online (Sandbox Code Playgroud)

正如所料,调用b确实返回"2".但是,调用a返回"1".何时执行return "1"时正在评估a

Rex*_*err 12

表格的所有*功能评估

f({code})
Run Code Online (Sandbox Code Playgroud)

相当于

val temp = { code }
f(temp)
Run Code Online (Sandbox Code Playgroud)

所以,在第一种情况下,

val temp = return "1"
None.foreach(temp)   // Never reach this point!
Run Code Online (Sandbox Code Playgroud)

而在第二,

val temp = (x: Nothing) => return 1
  // Equivalent: new Function1[Nothing,String]{ def apply(x: Nothing) = return "1" }
None.foreach(temp)   // Never call that weird function!
Run Code Online (Sandbox Code Playgroud)

所以一切都好.

但是,等一下,foreach拿一个A => Unit.如何为return "1"这样的功能?好吧,Scala从最可能的类型开始(Nothing这是任何事物的子类,因此承诺做任何你要求的事情,除非它不存在).然后,由于语句没有产生任何值(控制通过返回转义),它永远不会修改它Nothing.所以,确实Nothing是一个子类Function1[A,Unit].

并且要产生 - 并且Nothing假装生产它 - 你实际上运行代码,并返回.

*实际上,如果参数是按名称传递的,则会() => { Code }在没有评估的情况下秘密转换并传入.