天天看点

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()
	}