同文館

Kotlin的函数式编程思维

Kotlin的函数式编程思维

定义

学习编程之前,我们对函数的理解更多是数学上的定义例如 f=(x) ,学习了编程之后我们对函数的定义编程了一种方法(Method),方法更多的是它能做什么,而函数表示的则是输入到输出的映射。所以函数式编程更靠近与数学上函数的概念,输入到输出之间的一个映射关系。 显而易见的好处是输入固定,输出也是固定的。往函数里面输入一个值,用于有一个值以此对应。 函数式编程的特点

  • 函数是一种值
  • 不变性
  • 没有副作用

不变型和没有副作用,对于单一方法的调试,排查更加简单,加入线上出现某个Bug,开发者定位到了相关的函数,根据出现的结果推到出对应的输入值,在某个方法中的问题分析少去了其他无用的上下文理解。

####Lambda表达式的演进

public fun printUserName(name:String):Unit{
	print("User:"+name)
}

blockOfCode = fun printUserName(name:String):Unit{
							print("User:"+name)
				}
				
				
blockOfCode = printUserName(name:String):Unit{
						print("User:"+name)
				}				
				
blockOfCode = printUserName(name:String){
						print("User:"+name)
				}				
				
				
blockOfCode = (name:String){
						print("User:"+name)
				}	
				

blockOfCode = (name:String){
						print("User:"+name)
				}	
				
				
blockOfCode = (name){
						print("User:"+name)
				}	
				
					
blockOfCode = (name) ->	 print("User:"+name)
												

blockOfCode 函数的使用

val blockOfCode = (name) -> print("User:"+name)
blockOfCode("Tim")

####非纯函数与纯函数

//非纯函数
var preValue : Int = 2

fun addNotPure(currentValue : Int):Int {
    preValue = preValue + currentValue
    return preValue
}

//纯函数
fun addPure(cur : Int , pre : Int): Int {
    return cur + pre
}


高级函数

高阶函数是将函数用作参数或返回值的函数。

def add(x, y, f):
    return f(x) + f(y)

从Java 到Kotlin的实例应用

无限长的 if else,通过高级函数的特性可以对这钟场景做代码的拆解和重构

fun get(type:Int) {
	if(type  == TYPE_A) {
		return A()
	}else if (type  == TYPE_B) {
		return B()
	}else if (type  == TYPE_C) {
		return C()
	}else if (...) {
		return D()
	}else if (...) {
		return E()
	}else if (...) {
		return F()
	}
}

//函数式的写法

var fa = () -> A
fun fb = () -> B
fun fc = () -> C

fmap = mapOf(
	TYPE_A to fa,
	TYPE_B to fb,
	TYPE_C to fc,
)

fun get(type:Int) {
	return fmap(type)
}

库里化

curry:把一个函数的多个参数分解成多个函数, 然后把函数多层封装起来,每层函数都返回一个函数去接收下一个参数这样,可以简化函数的多个参数.

//普通
fun add(x: Int, y: Int): Int {
    return x + y
}


//柯理化
fun add(x: Int): (Int) -> Int {
    return fun(y: Int): Int {
        return x + y
    }
}

惰性求值

惰性求值时函数式编程语言常见的一种特性,就是不需要立刻运行,等待有需要时再执行“复杂”的运算。

fun makePowerFn(power: Double): (Double) -> Double {
    return fun(base: Double): Double {
        return pow(base, power)
    }
}

记忆功能

面对一些反复调用的函数,提高处理的性能,通过内存换取时间时一个常用的方法,遇到同样的参数无需重复运行即可直接返回计算结果。当然这是在纯函数的前提下

fun isEvenNumber(number: Int): Boolean {
   println("isEvenNumber")
   return number % 2 == 0
}

fun <X, R> memoizeFun(fn: (X) -> R): (X) -> R {
   val cache: MutableMap<X, R> = HashMap()
   return {
       cache.getOrPut(it, { fn(it) })
   }
}

fun main() {
   val m2 = memoizeFun { x: Int -> isEvenNumber(x) }

   val rm21 = m2(3)
   val rm22 = m2(3)
   val rm23 = m2(3)

   println(rm21)
   println(rm22)
   println(rm23)
}

语言库实现最佳体现

val ints = listOf(1, 2, 3, 4, 5, 6)
val strings = listOf("a", "b", "c", "d")

1.筛选


val list1 = ints.filter { it != 2 }
println("filter:$list1")


val list2 = ints.filterNot { it != 2 }
println("filterNot:$list2")

2.映射

val mlist = strings.map { s -> "hello $s" }
println("map:$mlist")

3.折叠

var sum = ints.reduce { acc, i -> acc + i }
println("Sum:$sum")

函数式编程应用于UI的发展

不同平台相同的趋势,由命令式转向声明式,甚至不同平台之间的视图函数和函数中参数的设置都极其相似。 1.React

2.Flutter

3.SwiftUI

4.Android Compose