3 回答

TA貢獻1802條經(jīng)驗 獲得超6個贊
首先,讓我們看看Scala規(guī)范告訴我們什么。第三章(類型)告訴我們功能類型(3.2.9)和方法類型(3.3.1)。第四章(基本宣言)談到價值宣言和定義?(4.1),?可變聲明和定義(4.2)和函數(shù)聲明和定義(4.6)。第六章(詞組)談到匿名函數(shù)(6.23)和方法值(6.7)。奇怪的是,函數(shù)值只在3.2.9上提到過一次,而在其他地方則沒有。
A?功能類型(大致上)是表單的一種類型。(T1,.,TN)=>U,這是特征的縮寫。FunctionN
在標(biāo)準圖書館里。匿名函數(shù)和方法值有函數(shù)類型,函數(shù)類型可以用作值、變量和函數(shù)聲明和定義的一部分。實際上,它可以是方法類型的一部分。
A?方法類型是非值型..這意味著不值-沒有對象,沒有實例-具有方法類型。如上文所述,a方法值實際上有一個功能類型..方法類型是def
聲明-關(guān)于def
除了它的身體。
價值聲明和定義和變量聲明和定義是val
和var
聲明,包括兩者類型和價值-分別可以是,功能類型和匿名函數(shù)或方法值..注意,在JVM上,這些(方法值)是用Java所稱的“方法”實現(xiàn)的。
A?功能聲明是def
聲明,包括類型和體體..類型部分是方法類型,而主體是表達式或塊..這也是用Java所謂的“方法”在JVM上實現(xiàn)的。
最后,匿名函數(shù)是功能類型(特征的一個例子)FunctionN
),以及方法值都是一樣的!區(qū)別在于方法值是通過后置下劃線(m _
是對應(yīng)于“函數(shù)聲明”的方法值(def
)?m
),或者通過一個名為ETA-擴張,這就像一種從方法到功能的自動轉(zhuǎn)換。
規(guī)格是這么說的,所以讓我把這個放在最前面:我們不使用這個術(shù)語!這會導(dǎo)致所謂的混亂“功能聲明”,這是程序的一部分(第4章-基本聲明)和“匿名函數(shù)”,這是一個表達式,并且“功能類型”這是一種類型-一種特質(zhì)。
以下術(shù)語和經(jīng)驗豐富的Scala程序員使用的術(shù)語與規(guī)范的術(shù)語有一處不同:而不是說功能聲明,我們說方法..甚至方法聲明。此外,我們注意到價值聲明和變量聲明也是實用的方法。
因此,考慮到上述術(shù)語的變化,下面是對這一區(qū)別的實用解釋。
A?功能是一個對象,該對象包括FunctionX
特征,如Function0
,?Function1
,?Function2
等可能包括PartialFunction
也是,這實際上擴展了Function1
.
讓我們看看其中一個特征的類型簽名:
trait?Function2[-T1,?-T2,?+R]?extends?AnyRef
這個特性有一個抽象的方法(它也有一些具體的方法):
def?apply(v1:?T1,?v2:?T2):?R
這告訴了我們所有需要知道的事情。一個功能有一個apply
接收N類型參數(shù)t1,?T2, ...,?總氮,并返回某種類型的東西。R
..它對它所接收的參數(shù)是對變的,在結(jié)果上是協(xié)變的.
這個差異意味著Function1[Seq[T], String]
是Function1[List[T], AnyRef]
..作為一個子類型意味著它可以被使用。代替它。如果我要打電話f(List(1, 2, 3))
并期望AnyRef
以上兩種類型中的任何一種都可以工作。
現(xiàn)在,什么是相似性一種方法和一種功能?好吧,如果f
是一個函數(shù)m
是一個局部變量的方法,那么這兩個方法都可以這樣調(diào)用:
val?o1?=?f(List(1,?2,?3))val?o2?=?m(List(1,?2,?3))
這些調(diào)用實際上是不同的,因為第一個調(diào)用只是一個語法糖。Scala將其擴展為:
val?o1?=?f.apply(List(1,?2,?3))
當(dāng)然,它是對象的方法調(diào)用。f
..函數(shù)還具有其他語法糖的優(yōu)勢:函數(shù)文字(實際上是其中的兩個)和(T1, T2) => R
輸入簽名。例如:
val?f?=?(l:?List[Int])?=>?l?mkString?""val?g:?(AnyVal)?=>?String?=?{ ??case?i:?Int?=>?"Int" ??case?d:?Double?=>?"Double" ??case?o?=>?"Other"}
方法和函數(shù)之間的另一個相似之處是,前者可以很容易地轉(zhuǎn)換為后者:
val?f?=?m?_
Scala將擴展那,那個,假設(shè)m
類型是(List[Int])AnyRef
轉(zhuǎn)入(Scala 2.7):
val?f?=?new?AnyRef?with?Function1[List[Int],?AnyRef]?{ ??def?apply(x$1:?List[Int])?=?this.m(x$1)}
在Scala2.8上,它實際上使用了AbstractFunction1
類以減少班級大小。
注意,一個函數(shù)不能反過來轉(zhuǎn)換-從一個函數(shù)轉(zhuǎn)換到一個方法。
然而,方法有一個很大的優(yōu)勢(嗯,兩個-它們可以稍微快一點):它們可以接收。類型參數(shù)..例如,同時f
上面可以指定List
它收到(List[Int]
(在示例中),m
可以參數(shù)化它:
def?m[T](l:?List[T]):?String?=?l?mkString?""
我認為這幾乎涵蓋了一切,但我很樂意用任何問題的答案來補充這一點。

TA貢獻2003條經(jīng)驗 獲得超2個贊
return
return
scala> val f = () => { return "test" }<console>:4: error: return outside method definition val f = () => { return "test" } ^
scala> def f: String = { | val g = () => { return "test" } | g() | "not this" | }f: Stringscala> f res4: String = test
scala> def f2: String = { | def g(): String = { return "test" } | g() | "is this" | }f2: Stringscala> f2 res5: String = is this

TA貢獻1865條經(jīng)驗 獲得超7個贊
功能可以使用參數(shù)列表調(diào)用函數(shù)以生成結(jié)果。函數(shù)具有參數(shù)列表、主體和結(jié)果類型。作為類、特征或單例對象的成員的函數(shù)被調(diào)用。方法..在其他函數(shù)中定義的函數(shù)稱為局部函數(shù)。帶有結(jié)果類型Unit的函數(shù)稱為過程。源代碼中的匿名函數(shù)稱為函數(shù)文本。在運行時,函數(shù)文本被實例化為稱為函數(shù)值的對象。
添加回答
舉報