天天看點

Kotlin學習筆記(三):Kotlin中的函數

一、函數的特性文法

  • 函數的幾種聲明形式
//普通聲明形式
	fun sayHello(str: String){
   	 	print(str)
	}

	//允許參數有預設值,可用于方法重載
	fun printName(str: String = "Irving"){
	    print(str)
	}

	//函數體隻有一行代碼時
	fun printlnName(str: String) = println(str)
           

二、函數嵌套

函數嵌套會降低代碼的可讀性,隻會在某些場景下時候運用:

  1. 某些條件下觸發遞歸的函數
  2. 不希望被外部函數通路到的函數
fun test(){
	
	    fun sayHello(count: Int = 10){
	        if (count > 0){
	            println("sayHello!!")
	            sayHello(count - 1)
	        }
   	 	}
	
	    sayHello()
	}
           

三、擴充函數和擴充參數

對三方

SDK

和無法控制的類,使用

Kotlin

可以很友善的對其進行擴充,添加成員方法和成員屬性。擴充函數是通過裝飾者模式,編譯時将擴充函數編譯為

Java

中的靜态方法,是以是靜态解析,不具備運作時的多态特性。

// 給String類添加擴充函數
	fun String.isIrving(): Boolean = this == "Irving"
	
	// 給String類添加擴充屬性
	var String.irving: String
	        get() = this
	        set(value) {
	            print(value)
	        }
           

調用時:

fun main(args: Array<String>) {
		//調用擴充函數
		print("Irving".isIrving())
		
	 	val a = "test"
	 	//設定擴充屬性的值
		a.irving = "Irving"
		print(a)
	}
           

四、Lambda閉包

  • Kotlin

    中的

    Lambda

    函數有以下特點
fun testLambda(){

	//一般寫法
    val thread01 = Thread({ -> println() })
    
    //如果Lambda表達式沒有參數,可以省略 ->
    val thread02 = Thread({ println() })
    
	//如果Lambda表達式是函數的最後一個參數,可以将Lambda表達式放在小括号的外面
    val thread03 = Thread(){ println() }

	//如果該函數隻有一個參數且該參數為Lambda表達式,可以省略小括号
    val thread04 = Thread {println()} 
}
           
  • 聲明閉包
val sayMessage = {message: String ->
    	println(message)
	}

	fun main(args: Array<String>) {
    	sayMessage("Irving")
	}
           

注意使用

Kotlin

聲明閉包時最多隻能含有22個參數。需要超過22個參數時需要自己手動添加對應的接口。

五、高階函數

高階:函數(

Lambda

)的參數是函數(

Lambda

)

//高階函數, 将函數聲明作為參數
	fun test(right: Boolean, block: () -> Unit){
		if (right) block()
	}

	//調用高階函數時,第二個參數傳入一個Lambda函數
	fun main(args: Array<String>){
		test(true){
			println("Hello World")
		}
	}
	
           

調用高階函數時必須傳入函數聲明,不能通過

Any.fun()

傳入,因為這樣是傳入方法的傳回值,

Kotlin

提供了

Any::fun

這種方式傳入函數聲明。

//高階函數, 将函數聲明作為參數
	fun test(right: Boolean, block: () -> Unit){
		if (right) block()
	}

	//調用高階函數時,第二個參數傳入一個函數聲明
	fun main(args: Array<String>){
		
		//建立一個Runnable對象
		val runnable = Runnable{
			println("Hello World")
		}

		//建立一個沒有傳回值的函數對象
		val function: () -> Unit 

		//将Runnable對象的run方法傳遞給function函數對象
		function = runnable::run
		
		//上面兩步可以簡化為:
		// val function = runnable::run

		//将function函數聲明作為參數傳遞給高階函數
		test(true, function)
	}
           

注意:

Kotlin

Lambda

表達式會被編譯為匿名對象,如果代碼中有大量重複的

Lambda

表達式,就會生成很多無用的臨時對象,這個時候可以使用

inline

關鍵字修飾高階函數,這樣當方法在編譯時就會拆解方法的調用為語句的調用,進而減少建立不必要的對象。但是過度使用

inline

關鍵字會加大編譯器的負擔,使代碼塊變得很龐大,查找問題變得更加困難,是以一般

inline

關鍵字隻用于修飾高階函數。

//使用inline關鍵字修飾高階函數, 将函數聲明作為參數
	inline fun test(right: Boolean, block: () -> Unit){
		if (right) block()
	}