函数

函数

val FINAL_HELLO_CHINA = "HelloChina" fun main(args: Array<String>) { // (Array<String>) -> Unit // checkArgs(args) // val arg1 = args[0].toInt() // val arg2 = args[1].toInt() // println("$arg1 + $arg2 = ${sum(arg1, arg2)}") // println(int2Long(3)) // println(sum(1, 3)) // println(sum.invoke(1, 3)) // args.forEach ForEach@{ // if(it == "q") return@ForEach // println(it) // } // // println("The End") println(sum) println(int2Long) println(::printUsage is ()-> Unit) } fun checkArgs(args: Array<String>) { if (args.size != 2) { printUsage() System.exit(-1) } } fun printUsage() { println("请传入两个整型参数,例如 1 2") // (Any?) -> Unit } // ()->Unit val sum = { arg1: Int, arg2: Int -> println("$arg1 + $arg2 = ${arg1 + arg2}") arg1 + arg2 } // (Int, Int) -> Int val printlnHello = { println("Hello") } // ()-> Unit val int2Long = fun(x: Int): Long { return x.toLong() } //Int Long String ABC // (Int) -> Long
  • 匿名函数
  • 具名函数::fun_name
  • 命名参数
  • 包级函数
  • Lambda表达式:{[参数列表] -> [函数体,最后一行是返回值]}
  • 如果函数参数的最后一个参数是Lambda表达式,可以把它移到()的外边,例如(){};如果()中什么也没有,可以把()删掉;如果传入的函数跟Lambda表达式是一样的,可使用::fun_name(函数引用)简化;跳出表达式,
  • return标签 ForEach@
  • 函数类型
  • () invoke()
  • 遍历数组 for(i in arr) args.forEach()
  • 扩展方法,有一个默认参数为调用该方法的实例
  • 具名参数
  • 默认参数
  • 单表达式可以省略花括号,在=号后指定代码体即可
  • 函数作用域:顶层函数、局部函数
  • 内联函数
  • Unit ==> void
args.forEach({it -> print(it)}) args.forEach({print(it)}) args.forEach(){print(it)} args.forEach{print(it)} args.forEach(::print)

闭包

闭包是由函数及其相关的引用环境组合而成的实体(即:闭包=函数+引用环境)。

  • 函数是什么

地球人都知道:函数只是一段可执行代码,编译后就“固化”了,每个函数在内存中只有一份实例,得到函数的入口点便可以执行函数了。在函数式编程语言中,函数是一等公民(First class value:第一类对象,我们不需要像命令式语言中那样借助函数指针,委托操作函数),函数可以作为另一个函数的参数或返回值,可以赋给一个变量。函数可以嵌套定义,即在一个函数内部可以定义另一个函数,有了嵌套函数这种结构,便会产生闭包问题。

单表达式函数

fun double(x: Int): Int = x * 2 fun double(x: Int) = x * 2

匿名函数

fun(x: Int, y: Int): Int = x + y fun(x: Int, y: Int): Int { return x + y } ints.filter(fun(item) = item > 0)

函数类型

FunctionN,N表示函数参数个数,0~22

Function0 Function1 Function2<in P1, in P2, out R>:Function<R> ... Function22

中缀表达式 infix

可变参数

可变参数 vararg,可以使用*操作符将可变参数以命名形式传入

fun main(vararg args: String) { // for (arg in args){ // println(arg) // } val list = arrayListOf(1,3,4,5) val array = intArrayOf(1,3,4,5) hello(3.0, *array) // 伸展(spread)操作符*,只能展开数组 } fun hello(double: Double, vararg ints: Int, string: String = "Hello"){ println(double) ints.forEach(::println) println(string) }

高阶函数

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