1. 函数的定义
推导:
2. 函数 vs 方法
所谓的方法,就是函数外面套了一个类,类中的函数就是方法。
3. 函数的类型
4. 函数的引用
4.1 函数的引用
4.2 函数的类型和引用
将函数引用赋值给一个变量(函数类型的变量)
4.3 函数的类型和引用(隐藏函数类型)
因为函数类型可以通过编译器推导出来,所以可以隐藏
4.4 函数类型和引用(类实例成对象)
4.4.1 函数类型少了一个参数Foo。并且获取引用是使用对象::方法
4.4.2 数学思维理解类实例化对象后的函数类型和引用
实例化对象后,就是绑定了receiver,他的函数类型跟类方法是不一样的,少了一个receiver作为函数类型
4.4.3 代码演示一下:
fun main(vararg args: String) {
println(args.contentToString())
// x的函数类型是(Foo, String, Long) -> Any
// x的函数类型也可以写成Foo.(String, Long) -> Any
// x的函数类型也可以写成 Function3<Foo, String, Long, Any>
val x = Foo::bar
val y: (Foo, String, Long) -> Any = x
val z: Function3<Foo, String, Long, Any> = x
// x函数类型作为参数
yy(x)
val f:() -> Unit = ::foo
val g:(Int) -> String = ::foo
val h:(Foo, String, Long) -> Any = Foo::bar
defaultParameter(y="Hello")
val(a, b, c) = multiReturnValues()
}
fun yy(p: (Foo, String, Long) -> Any) {
p(Foo(), "Hello", 3L)
// 调用的时候也可以写成invoke
p.invoke(Foo(), "Hello", 3L)
}
class Foo {
fun bar(p0: String, p1: Long): Any {
TODO()
}
}
fun foo() {}
fun foo(p0: Int): String {TODO()}
fun defaultParameter(x:Int = 5, y: String, z: Long = 0L) {
TODO()
}
fun multiReturnValues(): Triple<Int, Long, Double> {
return Truple(1, 3L. 4.0)
}
5. 变长参数
5.1 kotlin main函数的变长参数
// 变长参数定义: 当我们调用一个函数的时候,可以随便的传几个参数,这个个数在调用之前是不确定的
// 在调用的时候,传参的个数、类型都是确定的
// 这个东西跟数组描述的是一个概念,比如main函数,参数作为一个Array<String>
fun main(args: Array<String>) {
println(args.contentToString())
}
// vararg var 可变的,arg 参数
fun main(vararg args:String) {
println(args.contentToString())
// 调用自定义的变长参数函数
multiParameters(1, 2, 3, 4)
// listOf(1,2,3,4) listOf的实现就用到了变长参数
}
// 定义一个可以接受变长参数的函数
fun multiParameters(vararg ints: Int) {
// 变长参数怎么用呢?
// 变长参数其实跟数组是一回事,数组可以用的方法,变成参数也可以用。
// 变长参数当成数组来使用
// ints[i]
// ints.size
// ints.forEach
// ints的类型就是IntArray
println(ints.contentToString())
}
5.2 java main函数的变成参数
public static void main(String[] args) {
Syetem.out.println(Arrays.toString(args));
}
public static void main(String... args) {
System.out.lprintln(Arrays.toString(args));
}
6. 多返回值
在java中函数和方法返回的值只有一个,kotlin中就支持多个了吗?不是,是用了点手段。
用到了Triple和解构
fun multiReturnValues(): Triple<Int, Long, Double> {
return Triple(1, 3L, 4.0)
}
// 解构之后,a, b, c 分别对应Triple的类型
val(a, b, c) = multiReturnValues()
val r = a + b
val r1 = a + c
// 解构是Kotlin的语法糖,可以和Pair和Triple集合实现伪多返回值
7. 默认参数
7.1 默认参数一般从后往前放,避免编译器做困难的选择,编译器哪有那么聪明
如果默认参数不放在最后,在调用的时候"Hello" 不清楚是传给谁
8 具名参数
为了解决问题7.1,可以在传参的时候,指定赋值给哪个参数,具名的名是声明函数的形参的名
以下的调用,"Hello"是传给形参"y", 这样编译器就不会发疯了,知道传给具体哪一个参数了。