Kotlin學習2

1什麼時匿名函數

定義函數時不取名字的函數,我們稱之爲匿名函數,匿名函數通常整體傳遞給其他函數,或者從其他函數返回。
匿名函數對Kotlin來說很重要,有了他,我們能夠根據需要制定特殊規則,輕鬆定製標準庫裏的內置函數

fun main(){
  val total:Int = "Mississippi".count()
  println(total)//字符串長度
  
  val totalS:Int = 
    "Mississippi".count({letter->letter =='s'})
  println(totalS)//s字符個數
}

2函數類型與隱式返回

匿名函數也有類型,匿名函數可以當做變量賦值給函數類型變量,就像其他變量一樣,匿名函數就可以在代碼裏傳遞了。變量有類型,變量可以等於函數,函數也會有類型。函數的類型,由傳入的參數和返回值類型決定。
和具名函數不一樣,除了極少情況外,匿名函數不需要return關鍵字來返回數據,匿名函數會隱式或自動返回函數體最後一行語句的結果。

fun main(){
  //變量的類型是一個匿名函數
  val blessingFunction:()->String 
  blessingFunction = {
    val holiday = "National Day."
    "Happy $holiday"
  }
  println(blessingFunction())
}

3匿名函數參數

和具名函數一樣,匿名函數可以不帶參數,也可以帶一個或者多個任何類型的參數,需要帶參數時,參數的類型放在匿名函數的類型定義中,參數名則放在函數定義中

fun main(){
  val blessingFunction:(String)->String 
  blessingFunction = {name->
    val holiday = "National Day."
    "$name,Happy $holiday"
  }
  println(blessingFunction("Jack"))
}

4 it關鍵字

定義只有一個參數的匿名函數時,可以用it關鍵字表示參數名。當你需要傳入兩個值參,it關鍵字就不能用了。

fun main(){
  val blessingFunction:(String)->String 
  blessingFunction = {
    val holiday = "National Day."
    "$it,Happy $holiday"
  }
  println(blessingFunction("Jack"))
}

it非常重要,應用廣泛。函數式編程很多情況下都用

5匿名函數的類型推斷

定義一個變量時,如果已把匿名函數作爲變量賦值給他,就不需要顯示指明變量類型。

fun main(){
  val blessingFunction = {
    val holiday = "National Day."
    "Happy $holiday"
  }
  println(blessingFunction())
}

和java代碼塊要區分出來。

類型推斷也支持帶參數的匿名函數,但爲了幫助編譯器更準確的推斷變量類型,匿名函數的參數名和參數類型必須有。

fun main(){
  val blessingFunction:(String ,Int)->String = {name,year->
    val holiday = "National Day."
    "$name ,Happy $holiday $year"
  }

//或者下面這樣

  val blessingFunction = {name:String,year:Int->
    val holiday = "National Day."
    "$name ,Happy $holiday $year"
  }
  println(blessingFunction("Jack",2027))
}

6什麼是lambda

我們將匿名函數稱爲lambda,將他的定義稱爲lambda表達式,他的返回數據稱爲lambda結果。爲什麼叫lambda?lambda也可以用希臘字符“入”表示,是lambda演算的簡稱,lambda演算是一套數理演算邏輯,有數學家Alonzo Church於20世紀30年代發明,在定義匿名函數時 ,使用了lambda演算記法。

7定義參數是函數的函數

函數的參數是另一個函數

fun main(){
  val getDiscountWords = {goodsName:String,hour :Int ->
    val currentYear = 2027
    "${currentYear}年,雙11${goodsName}促銷倒計時:$hour 小時"
  }
  showOnBoard("衛生紙",getDiscountWords)
}

//具名參數
fun showOnBoard(goodsName:String,showDiscount::(String,Int)->String){
  val hour = (1..24).shuffled().last()
  println(showDiscount(goodsName,hour))
}

8簡略寫法

如果一個函數的lambda參數排在最後,或者是爲一個參數,那麼闊住lambda值參的一對圓括號就可以省略

fun main(){
  "Mississippi".count({it == 's'})
  "Mississippi".count{it == 's'}
}
fun main(){
  showOnBoard("衛生紙"){goodsName:String,hour :Int ->
    val currentYear = 2027
    "${currentYear}年,雙11${goodsName}促銷倒計時:$hour 小時"
  }
}

//具名參數
fun showOnBoard(goodsName:String,showDiscount:(String,Int)->String){
  val hour = (1..24).shuffled().last()
  println(showDiscount(goodsName,hour))
}

9函數內聯

lambda趨勢可以讓你更靈活的編寫應用,但是,靈活也是要付出代價的。
在JVM上,你定義的lambda會以對象實例的形式存在,JVM會爲所有同lambda打交道的變量分配內存,這就產生了內存開銷。更糟糕的是,lambda的內存開銷會帶來嚴重的性能問題。幸運的是,kotlin有一種優化內存機制叫內聯,有了內聯,JVM就不需要使用lambda對象實例了,因爲避免了變量內存分配。那裏需要使用lambda,編譯器就會將函數體複製黏貼到哪裏。
使用lambda的遞歸函數無法內聯,因爲會導致複製黏貼無限循環,編譯會發出警告。

10函數引用

要把函數作爲參數傳給其他函數使用,除了使用lambda表達式,kotlin還提供了其他方法,傳遞函數引用,函數引用可以把一個具名函數轉換成一個值參,使用lambda表達式的地方,都可以使用函數引用

fun main (){
  //要獲得函數引用,使用::操作符,後面跟要引用的函數名。
  showOnBoard("衛生紙",::getDiscountWords)
}
fun showOnBoard(goodsName:String,showDiscount:(String,Int)->String){
  val hour = (1..24).shuffled().last()
  println(showDiscount(goodsName,hour))
}
fun getDiscounWords(goodsName:String,hour:Int):String{
  val currentYear = 2027
  return "${currentYear}年,雙11${goodsName}促銷倒計時:$hour 小時"
}

11函數類型作爲返回類型

函數類型也是有效的返回類型

fun main(){
  val getDiscountWords = configDiscountWords();
  println(getDiscountWords("牙膏"))
}

fun configDiscountWords():(String)->String{
  val currentYear = 2027
  val hout=(1..24),shuffled().last()
  return { goodsName:String->
      hour +=20
      "${currentYear}年,雙11${goodsName}促銷倒計時:${hour}小時"
  }
}

12閉包

在kotlin中,匿名函數能夠修改並引用定義在自己作用域之外的變量,匿名函數引用着定義自身的函數裏的變量,Kotlin中的lambda就是閉包

能接受函數或者返回函數的函數又叫高級函數,高級函數廣泛應用於函數式編程當中。

java通過package吧作用於做好了;
kotlin作用域管理通過閉包。

13lambda與匿名內部類

java8支持面向對象編程和lambda表達式,但不支持將函數作爲參數傳給另一個函數或者變量,不過java的替代方案是匿名內部類。

java中做法:

創建了一個藉口、+匿名內部類

kotlin:

14小結

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章