在我沒有學習scala的時候,主要用java和python作平常工做開發,印象中,沒有特別的刻意的去區分method和function的區別,這個關係,正如咱們平常生活中,沒有刻意的去區分質量和重量。可是,他們之間,的確是有所不一樣的,這些不一樣也是創建在他們之間有聯繫的基礎之上!java
1. 如何定義python
首先,仍是引用英文原文來看看他們在定義上的區別和聯繫吧:es6
A Function Type is (roughly) a type of the form (T1, ..., Tn) => U, which is a shorthand for the trait FunctionN
in the standard library. Anonymous Functions and Method Values have function types, and function types can be used as part of value, variable and function declarations and definitions. In fact, it can be part of a method type.express
A Method Type is a non-value type. That means there is no value - no object, no instance - with a method type. As mentioned above, a Method Value actually has a Function Type. A method type is a def
declaration - everything about a def
except its body.app
2. 具體例子分析函數
1 scala> def m1(x:Int) = x+3 2 m1: (x: Int)Int 3 4 scala> val f1 = (x: Int) => x+3 5 f1: Int => Int = <function1>
看到沒,方法定義和函數定義是否是在scala的解析器signature上就有顯示了,def m1(x: Int) = x+3就是一個簡單的method的定義。signature中m1: (x: Int)Int 表示method m1有一個參數Int型參數x,返回值是Int型。學習
val f1 = (x: Int) => x+3則是function的定義,解析器的signature中f1: Int => Int = <function1>表示function f1的method體接受一個Int型的參數,輸出結果的類型是Int型。this
從上面的例子,得出一個總結:es5
方法是一個以def開頭的帶有參數列表(能夠無參數列表)的一個邏輯操做塊,這正如object或者class中的成員方法同樣。spa
函數是一個賦值給一個變量(或者常量)的匿名方法(帶或者不帶參數列表),而且經過=>轉換符號跟上邏輯代碼塊的一個表達式。=>轉換符號後面的邏輯代碼塊的寫法與method的body部分相同。
3. 區別都還有那些?
method能夠做爲一個表達式的一部分出現(調用函數並傳參),可是method(帶參方法)不能做爲最終的表達式(無參方法能夠,可是這個就成了方法調用,由於scala容許無參方法調用時省略()括號),而function能夠做爲最終的表達式出現。 |
1 scala> m1 2 <console>:12: error: missing arguments for method m1; 3 follow this method with `_' if you want to treat it as a partially applied function 4 m1 5 ^ 6 7 scala> f1 8 res1: Int => Int = <function1>
method能夠沒有參數列表,參數列表也能夠爲空。可是function必須有參數列表(也能夠爲空)。方法名意味着方法調用,函數名只是表明函數自身 |
1 scala> def m2 = 100; 2 m2: Int 3 4 scala> def m3() = 1000; 5 m3: ()Int 6 7 scala> var f2 = => 100; 8 <console>:1: error: illegal start of simple expression 9 var f2 = => 100; 10 ^ 11 12 scala> var f2 =()=> 100; 13 f2: () => Int = <function0>
1 scala> m2 2 res2: Int = 100 3 4 scala> m3 5 res3: Int = 1000 6 7 scala> m3() 8 res4: Int = 1000 9 10 scala> f2 11 res5: () => Int = <function0> 12 13 scala> f2() 14 res6: Int = 100
在函數出現的地方咱們能夠提供一個方法。 這是由於,若是指望出現函數的地方咱們提供了一個方法的話,該方法就會自動被轉換成函數。該行爲被稱爲ETA expansion。 注意: 指望出現函數的地方,咱們可使用方法。 不指望出現函數的地方,方法並不會自動轉換成函數 在scala中操做符被解釋稱方法:
|
1 scala> val ml = List(1,2,3,4) 2 ml: List[Int] = List(1, 2, 3, 4) 3 4 scala> ml.map((x)=>2*x) 5 res0: List[Int] = List(2, 4, 6, 8) 6 7 scala> def m(x:Int) = 2*x 8 m: (x: Int)Int 9 10 scala> ml.map(m) 11 res1: List[Int] = List(2, 4, 6, 8) 12 13 scala> def m(x:Int) = 3*x 14 m: (x: Int)Int 15 16 scala> ml.map(m) 17 res2: List[Int] = List(3, 6, 9, 12)
能夠在方法名後面加一個下劃線強制變成函數。 注意: 方法名與下劃線之間至少有一個空格喲! |
1 scala> def m3(x: Int): Int = x * x * x 2 m3: (x: Int)Int 3 4 scala> val f3 = m3_ 5 <console>:10: error: not found: value m3_ 6 val f3 = m3_ 7 ^ 8 9 scala> val f3 = m3 _ 10 f3: Int => Int = <function1> 11 12 scala> f3(3) 13 res0: Int = 27