Day2 函数 与 Lambda 闭包

0 阅读1分钟

函数的特性语法

fun echo(name: String){
    println("$name")
}
fun echo(name: String = "Amy"){
    println("$name")
}
fun echo(name:String) = println("$name")
可以看出几乎和Swift 一模一样,除了 fun 和func 最大的差别就是单表达式,这个在基础语法我们聊过

嵌套函数

fun function() {
    val str = "hello world"
    fun say(count: Int = 10) {
        println(str)
        if (count > 0) {
            say(count - 1)
        }
    }
    say()
}
嵌套函数、捕获外部变量、默认参数值,Swift和Kotlin行为一致,语法几乎一样

扩展函数

fun File.readText(charset:Chatset = Charsets.UTF_8) : String 
= readBytes().toString(charset) //单表达式,这是函数体

Swift

extension File {
    func readText(charset:Charset = .utf8) -> String {
        return readBytes().toString(charset)
    }
}
Kotlin用fun 类名.方法名替代了Swift的extesnsion块

扩展函数的静态解析
open class Animal
class Dog : Animal()
fun Animal.name() = "animal"
fun Dog.name() = "dog"

fun Animal.printName(anim:Animal){
    println(anim.name())//这里虽然传了Dog,但是只认Animal
}

fun main(){
    Dog().printName(Dog())// 输出"animal"
}
Kotlin的扩展函数编译后与类无关,参数类型在编译期就已确定,运行时不管传入的是不是Dog,一律按声明类型Animal处理,不支持多态。Swift的extension则是真正加入类中的方法,运行时能识别实际类型,传入Dog就调Dog的方法,支持多态。

Lambda闭包语法

Kotlin 叫Lambda,Swift 叫Closure,本质是一个东西,甚至连语法糖都是极为的相似。
Kotlin
val echo = { name:String -> 
    println(name)
}
Swift
let echo = { name:String in
    print(name)
}
in 换成 -> 其他一致
语法糖
1 无参数语法糖
    val run = {
        println("hello")
    }
2 尾随闭包(最后一个参数是Lambda)
Thread(){}
Thread{}// 只有一个参数时连小括号也能省
3 it 关键字(这里和Swift不一样)
//Kotlin 单参数Lambda,参数名自动叫it,可以不声明
val echo:(String) -> Unit = {println(it)}
//Swift用$0 $1 这种匿名参数
let echo:(String) -> Void = {print($0)}
4 调用方式
echo("Amy")// 两者都可以直接调用
echo.invoke(“Amy”) //Kotlin独有,用invoke显示调用
Kotlin可空Lambda必须用 `?.invoke`,Swift直接 `?.()` 就行。

高阶函数

Swift和Kotlin都支持函数作为参数,map filter reduce 这些本质就是系统内置的高阶函数,自定义写法两边几乎一致,只是单参数简写Swift用$0,Kotlin 用it。

内联函数

不加 inline,Lambda是一个对象,每次调用都会创建一个新对象 加了 inline,编译器直接把Lambda的代码复制粘贴到调用的地方,不创建对象: 类比Swift的 @inline,思路完全一样,用空间换时间,把函数调用展开成代码直接执行,减少对象创建的开销。