Kotlin學習筆記(九)函式,Lambda表示式

2021-08-02 14:49:53 字數 3547 閱讀 2248

函式

kotlin中,使用fun關鍵字定義乙個函式,函式引數使用 pascal 表示法定義,即 name: type。引數用逗號隔開。每個引數必須有顯式型別。

fun foo(arg1:string,arg2:boolean,arg3:int):int
當函式只有單個表示式時,可以省略花括號,直接寫在=之後,如果返回值型別可由編譯器推斷出來,也可以省略返回值型別:

fun foo(arg1:string,arg2:boolean,arg3:int)=1

//省略花括號和返回值型別後的函式形式

具有塊**體的函式,必須顯式指定返回值型別,除非返回值型別是unit。編譯器不會推斷具有塊**體的函式的返回型別,因為這樣的函式在**體中可能有複雜的控制流,並且返回型別對於讀者(又是甚至是編譯器)是很不明顯的。

fun foo(arg1:string,arg2:boolean,arg3:int):int
呼叫函式使用傳統的方法

var

value=foo()

成員函式的呼叫要使用點表示法

r().foo()
函式還可以使用中綴表示法來呼叫,當滿足一下條件時:

infix fun int.add(x:int):int

fun printadd()

我們還可以在呼叫函式的時候使用命名的引數:

fun foo(arg1:string="hello kotlin",arg2:boolean,arg3:int)

fun printfoo()

函式引數可以有預設值,當省略相應的引數時使用預設值。與其他語言相比,這可以減少過載數量。

fun foo3(arg1: string,arg2: boolean=false,arg3: int=0)

fun printfoo3()

我們還可以為函式定義可變數量的引數,只要用vararg關鍵字修飾即可:

//可變數量的引數

fun foo4(vararg args:int)

}fun printfoo4()

如果我們已經有乙個陣列並希望將其內容傳給該函式,我們使用伸展(spread)操作符(在陣列前面加 *):

//可變數量的引數

fun foo4(vararg args:int)

}fun printfoo4()

高階函式

高階函式可以將乙個函式作為引數或返回值:

fun add2(x:int=0,y:int=0):int

fun operate(x:int=0,y:int=0,body:(int,int)->int)

fungetvalue

()

lambda表示式

以上的operate()方法,我們還有乙個更簡潔的呼叫方式,即傳入乙個lambda表示式:

fun getvalue())

//函式引數傳入乙個lambda表示式

}

lambda 表示式的完整語法形式,即函式型別的字面值如下:

val sum =
lambda 表示式總是被大括號括著, 完整語法形式的引數宣告放在括號內,並有可選的型別標註, 函式體跟在乙個 -> 符號之後。如果推斷出的該 lambda 的返回型別不是 unit,那麼該 lambda 主體中的最後乙個(或可能是單個)表示式會視為返回值。

如果我們把所有可選標註都留下,看起來如下:

val sum: (int, int) -> int =
當函式引數是最後函式的最後乙個引數,並且你傳入乙個lambda表示式作為相應的引數,則可以在圓括號之外指定它:

fun getvalue())

//函式引數傳入乙個lambda表示式

operate(3,7)

}

如果lambda表示式只有乙個引數,kotlin可以自己計算出簽名,它允許我們不宣告唯一的引數,並且隱含的為我們宣告其名稱為it:

fun upcase(str:string,body:(string)->string):string

funtransform

()}

如果lambda表示式是呼叫的唯一引數,則呼叫中的圓括號可以完全省略:

fun string.upper(body:(string)->string):string

funtransform

()//lambda是呼叫的唯一引數,則呼叫的圓括號可以省略

}

匿名函式

匿名函式與常規函式一樣,只是省略了函式名稱而已:

fun string.upper(body:(string)->string):string

funtransform

()//lambda表示式是呼叫的唯一引數,則呼叫的圓括號可以省略

"hellokotlin".upper

(fun(str:string):string)

}

lambda表示式和匿名函式之間的另乙個區別是非區域性返回的行為。乙個不帶標籤的 return 語句總是在用 fun 關鍵字宣告的函式中返回。這意味著 lambda 表示式中的 return 將從包含它的函式返回,而匿名函式中的 return 將從匿名函式自身返回。

fun foo() 

}

值得注意的是:這種非區域性的返回只支援傳給內聯函式的 lambda 表示式。 如果我們需要從 lambda 表示式中返回,我們必須給它加標籤並用以限制 return。

fun transform():string

"hellokotlin".upper(fun(str:string):string)

}

帶接收者的函式字面值

kotlin提供了指定的接收者呼叫函式字面值的功能。在函式字面值的函式體中,可以呼叫該接收者物件上的方法而無需任何額外的限定符。

這樣的函式字面值的型別是乙個帶有接收者的函式型別:

sum : int.(other: int) -> int
該函式字面值可以這樣呼叫,就像它是接收者物件上的乙個方法一樣:

1.

sum(2)

匿名函式語法允許你直接指定函式字面值的接收者型別。 如果你需要使用帶接收者的函式型別宣告乙個變數,並在之後使用它,這將非常有用。

val sum = fun int.(other: int): int = this + other

kotlin學習筆記

屬性委託在單獨一頁中講 屬性委託。委託模式已經證明是實現繼承的乙個很好的替代方式,而 kotlin 可以零樣板 地原生支援它。derived類可以通過將其所有公有成員都委託給指定物件來實現乙個介面base inte ce base class baseimpl val x int base clas...

Kotlin學習筆記

該系列文章是本人梳理kotlin基礎知識所作,時間倉促可能會有不足,歡迎指正!kotlin學習筆記 1 基礎語法 kotlin學習筆記 2 基本資料型別,字串與陣列 kotlin學習筆記 3 條件控制與迴圈控制 kotlin學習筆記 4 容器 kotlin學習筆記 5 泛型和高階函式應用 kotli...

Kotlin筆記 infix函式

使用infix函式構建函式,可以使函式的呼叫有更強的可讀性。在kotlin中我們可以使用a to b的方式來構建乙個鍵值對,但這裡的to並不是關鍵字,而是採用kotlin提供的一種高階語法糖規則進行了調整,a to b這樣的寫法其實等價於a.to b 下面我們來看一看to 函式的原始碼吧,如下 pu...