梳理学习Kotlin,函数式编程

概念:

​ 一切皆可视为函数。与面向对象(OOP),‘一切皆对象’ 相对应 ‘一切皆函数’也是函数式编程的含义。包括经常被形象成为,函数在Kotlin中是一等公民,这句话也是相对OOP编程范式中,方法必须依托类或对象才能存在。对象可以被传递,函数也可以被传递,对象可以作为返回值,函数也可以作为返回值。

如何理解Lambda expression

​ 个人理解为,代数方程,函数的输入和输出明确后,方程式就已经定好 y = n * m,对于输入为类型为n, m,返回值为y类型的函数,都可以转换为相同的函数签名,数学上叫‘泛函数’, 即lambda。lambda简化了函数的定义。

为什么要称为‘高阶’函数

​ wiki上定义为,接受一个或多个函数作为输入,或输出一个函数。所以“高”对应的“低”,是指不符合这两个条件,也就是一阶函数(first-order function),不依赖其他函数,有直接返回值(类似递归基)。所以“高阶”对应了函数映射到另一个“低阶”函数,最终求解。

如何理解懒加载

​ 需要计算,才计算其中内容,声明函数,传递函数,不会导致函数执行

高阶函数实例
fun twice(f: (Int) -> Int): (Int) -> Int = { x ->
    f(f(x))
}

val plusTwo = twice { it + 1 }
val plusTwo = twice { it::inc //函数式 }

println(plusTwo.invoke(2))
println(twice { it + 1 }.invoke(2))
一些作用域高阶函数
getUserName()?.let {
    // it, 无返回值,空安全
}

val name = getUserName().apply {
    // this, 返回自身,用于同一个对象多次调用
}

val name = with(getUserName()) {
    // this, 返回最后一行,用于泛对象多次调用
    "Hello"
}

val name = getUserName()?.run { 
    // this, 返回最后一行, 空安全,常用于缩小变量作用域
    "Hello"
}

val name = getUserName()?.also { 
    // it, 返回自身,空安全,用于日志,拦截
}

// Closeable 使用后释放
val name = File("book.txt")
    .bufferedReader()
    .use { it.readLine() }
// Closeable 使用后释放
val name = File("book.txt")
    .useLines { 
        println(it)
    }
带接收者的Lambdas

​ 上面apply和let两个高阶函数的差异为

public inline fun <T, R> T.let(block: (T) -> R): R
public inline fun <T> T.apply(block: T.() -> kotlin.Unit): T

T.() -> kotlin.Unit被称为带接收者的lambda,可以理解为扩展方法类似的实现,将输入It,替换为this.

Lazy 懒加载
public fun <T> lazy(initializer: () -> T): kotlin.Lazy<T>
val name by lazy {
    "Brook"
}

val friends = sequenceOf("Lucy, Eric, Tom")
val nums = (1..1000).asSequence()

By lazy 将实现委托,返回了kotlin.Lazy,当调用到的时候,才会真正的调用initializer: () -> T,实现大对象,延迟初始化,非必要对象不初始化,减少性能损耗。

​ 而对于集合,连续的数据,则是通过Sequence来实现,类似于Java8的Stream,操作符分为中间操作符,如ma p, filter 和终结操作符,take, toList(), 将数据以数据流的形式发送,处理。降低大集合内存占用和不必要的数据的占用。

性能差异

普通集合类似于批处理,一次求解,大数据量复杂操作,性能提升明显。

val timeSquence = measureTimeMillis {
    val nums = (1..1000000).asSequence()
        .filter { (it and 1) == 1 }
        .take(2)
}
println(timeSquence)
val time = measureTimeMillis {
    val nums = (1..1000000)
        .filter { (it and 1) == 1 }
        .take(2)
}
println(time)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值