一個類可以很好得的call-by-名稱參數,只要他們不val
或var
:
> scala
Welcome to Scala version 2.11.1 (Java HotSpot(TM) 64-Bit Server VM, Java 1.7.0_55).
Type in expressions to have them evaluated.
Type :help for more information.
scala> class Foo(f: => Unit) {
| def run(): Unit = f
| }
defined class Foo
scala> new Foo(println("hello"))
res0: Foo = [email protected]
scala> res0.run()
hello
一個val
或var
參數不能用名字的原因很簡單,一個class字段不能是名稱,不能超過局部變量。所以下面是無效的:
scala> class FooInvalid(val v: => Unit) {
<console>:1: error: `val' parameters may not be call-by-name
class FooInvalid(val v: => Unit) {
^
但是,可能有被分配了一個用名字參數,作爲功能到val
場,像這樣(但你必須使用()
爲調用點):
scala> class FooVal(v0: => Unit) {
| val v:() => Unit =() => v0
| }
defined class FooVal
scala> new FooVal(println("hello"))
res2: FooVal = [email protected]
scala> res2.v
res3:() => Unit = <function0>
scala> res2.v()
hello
最後,而不是定義v
爲() => Unit
型val
,你可以把它定義爲Unit
型def
。然後你讓你在第一時間大概想要的行爲:
scala> class FooDef(v0: => Unit) {
| def v: Unit = v0
| }
defined class FooDef
scala> new FooDef(println("hello"))
res5: FooDef = [email protected]
scala> res5.v
hello
有人可能會說編譯器應該做的這種轉變本身,但不會與語義一個val
必須一致穩定 (例如,一個穩定的值,您可以import x._
其成員,你不能做一個不穩定的值),因爲def
(即使沒有()
)是一個不穩定的值。最好把這個小改寫留給用戶,而不是引入一個非常奇怪的缺點。
但是,如果他們是'val',那就是我的問題。對不起,應該是更具體。 – acjay
好的。考慮到這一點,我已經更新了我的答案。 – sjrd
很好的答案。關於你與局部變量的比較,局部變量不能是名稱,但可能是懶惰的。儘管如此,編譯器還是抱怨這一點,建議使用名字參數,不要少。 – acjay