函数是一个类型,就像编程语言中的基本类型一样,就像Java中的引用类型一样,函数是函数类型。基本类型、引用类型、函数类型,说白了物理空间就是内存的一段区域,逻辑空间叫什么基本类型、引用类型、函数类型。基本类型就是int, float这种存储数据的,引用类型就是类呗,一个类在内存中不也是一段区域嘛,函数类型就是一段操作流程呗,一段操作流程在内存中不也是一段区域嘛。总之一样啦。猫是动物,狗是动物,人家棕熊也是动物啦,都在地球上占据一定的空间,不能把人家当成空气。
既然他们都是一种类型,那就要同等对待,既可以作为变量,也可以作为常量;既可以作为函数形参,也可以作为函数返回值。猫和狗能结婚生子,人家棕熊也可以,不可以把人家阉割了。物物平等。
fun add(a: Int, b: Int) : Int {
return a + b
}
上面这个棕熊,哦,不对,函数,上面这个函数的类型是啥?
不知道吧,我告诉你,是这个:
(Int, Int) -> Int
惊不惊喜?咦,看不懂?回去补补lambda表达式去,老衲不负责给你补基础知识。哇咔咔!
好啦,既然函数有类型了,那我们用函数声明变量吧,它和用基本类型,用类声明变量是一样一样嘀。
var myfun : (Int, Int) -> Int //函数类型
var myBase : Float //基本类型
var myClass : String //引用类型
从此,江湖上出现了三剑客:基本类型、函数类型、引用类型。打遍天下无敌手。
定义完类型了,我得赋值啊,要不我定义类型干啥。
客官请看下面内容:
myfun = :: add //使用函数引用要用::,不能加(),因为加()就变成调用函数了,而不是使用函数引用
myBase = 1.5f
myClass = String("你瞅啥,我就喜欢用String的构造函数咋地") //实例化对象不需要用new了,直接用对象的构造函数
myClass = "当然,直接这样写也是可以的"
再来,函数类型作为形参:
fun sum(a: Int, b: Int, fn: (Int, Int) -> Int): Int {
return fn(a, b)
}
我就喜欢把函数类型传进去,咋嘀!
再来,函数类型作为返回值:
fun getMathFunc(type: String): (Int, Int)-> Int {
// 定义一个计算加法的局部函数
fun add(a: Int, b: Int) : Int {
return a + b;
}
// 定义一个计算减法的局部函数
fun sub(a: Int, b: Int) : Int {
return a - b;
}
// 定义一个计算乘法的局部函数
fun mul(a: Int, b: Int) : Int {
return a * b;
}
when(type) {
"add" -> return ::add
"sub" -> return ::sub
else -> return ::mul
}
}
fun main(args: Array<String>) {
var mathFunc = getMathFunc("add") //得到add函数
println(mathFunc(5, 3)) //输出8
mathFunc = getMathFunc("sub") //得到sub函数
println(mathFunc(5, 3)) //输出2
mathFunc = getMathFunc("mul") //得到mul函数
println(mathFunc(5, 3)) //输出15
}