2016-05-22 36 views
1

在Python我可以這樣做:功能分配到值/變量斯卡拉

In [24]: def m1(): 
    ....:  return "I am legend" 
    ....: 

In [25]: f1 = m1 

In [26]: type(f1) 
Out[26]: function 

In [27]: type(m1) 
Out[27]: function 

而在Scala中,

def m1() = "I am legend" 

的就是我上面做的相當的不

val f1 = m1 

但我反而必須指定

scala> val f1:()=> String = m1 
f1:() => String = <function0> 

scala> val f1 = m1 _ 
f1:() => String = <function0> 

爲什麼這個設計選擇做? 正如有人來斯卡拉從Python中,能夠通過

val f1 = m1 

分配的功能似乎比不必做上述方法中的一個更自然。

我知道val f1 = m1

結果m1被調用,並將所得值分配給f1但不會是一直更加清晰遵循了Python方法 ,需要在這種情況下,括號,而不是即

val f1 = m1() 

在我希望調用函數並將結果分配給f1的情況下?

+3

這是一個設計選擇。允許arity-0的方法省略括號意味着'val f1 = m1'不能既是方法調用又是函數分配。像大多數事情一樣,這是一種折衷。設計人員雖然省略括號會更有用,因爲它會比將函數分配給方法更多。 –

回答

2

在Scala中,如果方法沒有副作用,可以大大提高可讀性,則應該省略括號。從Scala docs引用:

Scala的允許括號對元數-0的方法(無 參數)遺漏。但是,只有當方法 沒有副作用(純功能)時才應使用此語法。換句話說, 在調用queue.size, 時忽略括號是可以接受的,但在調用println()時不會。這個約定反映了上面給出的方法 聲明約定。

宗教上遵守這一慣例將大大改善代碼 的可讀性,並將使它更容易理解一目瞭然的任何給定方法的最基本的操作。抵制省略 括號的衝動只是爲了保存兩個字符!

有一些更深層次的考慮,在這個關於統一訪問 原則。他們在Martin Odersky等人的「Programming in Scala」一書中的10.3節中闡述。我不會在這裏引用它(它超過兩頁長),但重點是在調用arity-0方法時忽略括號可以讓您無縫地將這些方法更改爲vals,甚至無需觸摸客戶端的代碼。這樣做,您可以管理通常的時間和空間折衷。特別是,你可以override defs with vals(但不是反之亦然):

abstract class Mass { 
    def kilograms: Double 
} 

class Grams(grams: Double) extends Mass { 
    val kilograms: Double = { 
    Thread.sleep(5000) // pretend to think hard 
    grams/1000.0 
    } 
} 

More on def vs val vs lazy val

當然,這一切的東西就不會如蟒蛇般的分配被允許成爲可能。