2016-05-21 144 views
4

有人可以解釋以下對我說:功能VS函數指針

scala> def squared(x: Int) = x * x 
squared: (x: Int)Int 
scala> val sq : (Int) => Int = squared 
sq: Int => Int = <function1> 
scala> sq.getClass 
res111: Class[_ <: Int => Int] = class $anonfun$1 

我明白這一點,到目前爲止,方是一個功能,而平是一個函數指針。

但後來我這樣做:

scala> squared.getClass 
<console>:13: error: missing arguments for method squared; 
follow this method with `_' if you want to treat it as a partially applied function 
    squared.getClass 
^

爲什麼我不能調用上平方的getClass?畢竟,不是函數第一類對象?爲什麼我需要這樣做才能起作用?

scala> squared(7).getClass 
res113: Class[Int] = int 

而且我也得到

scala> sq(5).getClass 
res115: Class[Int] = int 

相同的結果來想想吧,爲什麼

scala>squared(5) 

scala> sq(5) 

產生相同的結果,即使一個是功能,而且其他一個函數指針,而不需要使用不同的語法? 類似於*sq(5)的東西可能已經更清晰了,不是嗎?

+0

我相信這與def vs val有關。 Def在評估時調用val,當定義時。這可能有更多的信息:http://stackoverflow.com/questions/18887264/what-is-the-difference-between-def-and-val-to-define-a-function –

回答

3

我明白這一點,squared是一個函數,而sq是一個函數指針。

錯誤。斯卡拉既沒有明確的指針也沒有功能指針

scala> (squared _).getClass 
res4: Class[_ <: Int => Int] = class $anonfun$1 

scala> sq.getClass 
res5: Class[_ <: Int => Int] = class $anonfun$1 

scala> :type squared _ 
Int => Int 

scala> :type sq 
Int => Int 

兩者都有相同的類型。不同之處在於defd的函數與vals或vars不在同一個命名空間中,引用其的代碼與引用另一個的代碼的解析不同。

具體而言,對val的引用是可以評估的表達式。對函數def的引用不是表達式,您不能應用僅適用於值的運算符.

+0

「平方」並不真正有與'sq'類型相同,因爲'squared'在這個意義上根本沒有類型 - 它不是一個表達式。你可以寫':type squared _'只是因爲你明確地用'_'擴展它。 –

+0

@TravisBrown正確。這就是我在最後一段中所說的。 – Marcin

10

指針的概念在這裏並不真正相關,或者更一般地在Scala(或JVM)中。 squaredsq之間的區別在於squared是一種方法,而sq是一種功能。

Scala(主要)是一種旨在編譯爲JVM字節碼的語言。 JVM沒有第一類功能,但它有一些方法,它們與類的一個實例(實例方法)或簡單地與類本身(靜態方法)相關聯。從這個意義上說,方法與JVM的對象有着根本不同的類型 - 它們不能作爲其他方法的參數傳遞,等等。

由於Scala是一種函數式語言,函數式語言構建於更高階的函數和更一般的第一類函數,Scala語言設計者需要能夠以在JVM上工作的方式對函數進行編碼。這是通過Function1 class做的,當你寫這樣的事:

val sq: (Int) => Int = x => x * x 

您正在使用Scala的語法糖用於創建Function1類的實例。這些東西都是編碼爲JVM對象的函數,所以它們可以作爲語言中的第一類東西來處理。但是,斯卡拉並沒有放棄方法的想法。由於部分原因與Scala的功能OOP雜交有關,部分與性能問題有關,大多數Scala程序大量使用def定義,這些定義定義了方法,而不是Function1意義上的「功能」。 Scala提供了一個特殊的轉換過程(稱爲eta擴展),通過這個過程可以在許多情況下將方法看作函數(包括這裏定義的sq的右側)。

如果這一切似乎令人困惑,相信我,它是。儘管如此,過一段時間後你會習慣它(儘可能快地理解指針)。

+0

非常啓發性的答案! –