从“Scala编程”一书中可以看出:
var assertionsEnabled = true
def myAssert(predicate: () => Boolean) =
if (assertionsEnabled && !predicate())
throw new AssertionError
myAssert(() => 5 > 3)
使用空参数列表很尴尬。 Scala提供了by-name参数来解决这个问题。
def byNameAssert(predicate: => Boolean) =
if (assertionsEnabled && !predicate)
throw new AssertionError
byNameAssert(5 > 3)
我在讨论中有一个混乱.myAssert接受一个函数参数,该参数不带参数并返回一个布尔值。
byNameAssert的输入类型是什么?与myAssert相同吗?对我来说,似乎是一个表达式,它计算为一个布尔值,并且以名字形式表示它表示只要调用表达式就会计算,而不是被传递给byAssert.But然后它与myAssert的输入类型不同。如果是这种情况,那么byAsAssert和myAssert是完全不同的。
答案 0 :(得分:0)
对我来说,它似乎是一个表达式,它计算为一个布尔值,并且以名字形式表示它意味着只要调用它就会计算表达式,而不是在传递给byAsAssert时计算它。
是。但它实现的方式是Scala将byNameAssert
和myAssert
编译为完全相同的代码(不同的@ScalaSignature
注释除外)以及每当它看到{{1}之类的调用时它们被重写,因此下一个编译器阶段将参数视为byNameAssert(5 > 3)
。
答案 1 :(得分:0)
byNameAssert的输入类型是什么?
=> Boolean
与myAssert相同吗?
不,myAssert
期望() => Boolean
作为参数。虽然"道德相同",但它被编译器视为一个单独的类型。
=> Boolean
- 事物既不是() => Boolean
,也不是Boolean
。以下小例子应该进一步说明这一点。尝试将有条件的foo
分配给() => Boolean
和Boolean
类型的变量失败:
scala> def foo(b: => Boolean): Unit = {}
foo: (b: => Boolean)Unit
scala> val f: Boolean => Unit = foo _
<console>:12: error: type mismatch;
found : (=> Boolean) => Unit
required: Boolean => Unit
val f: Boolean => Unit = foo _
^
scala> val f: (() => Boolean) => Unit = foo _
<console>:12: error: type mismatch;
found : (=> Boolean) => Unit
required: (() => Boolean) => Unit
val f: (() => Boolean) => Unit = foo _
^
但这有效:
scala> val f: (=> Boolean) => Unit = foo _
f: (=> Boolean) => Unit = $$Lambda$1090/668948486@69bc9584
因此,虽然从实现的角度来看,=> Boolean
与() => Boolean
基本相同,但它被分别视为一种不同的类型,并且当涉及到语法脱离时它的行为完全不同表达式和代码块作为参数传递给函数。