Kotlin开发安卓APP笔记-函数和lambda表达式(2)
来源:互联网 发布:windows media center 编辑:程序博客网 时间:2024/06/07 13:05
接着上一篇Kotlin开发安卓APP笔记-函数和lambda表达式(2)继续学习
可变参数数量Varargs
使用“vararg”关键字修饰参数,即可定义为可变数量参数(一般是最后一个参数):
fun asList(vararg ts: Any): List<Any> { val result = ArrayList<Any>() for (t in ts) { result.add(t) } return result }
等同Java版:
List<Object> asList(Object... ts){ List<Object> result=new ArrayList<>(); for (Object t:ts) { result.add(t); } return result; }
该函数可以接收不定个数参数:
val list = asList(1, 2, 3) val list2 = asList("bestmk.cn","猫客技术论坛")
在函数内部,被“vararg”修饰的参数实际上是一个数组(Array< out T>)。
一个函数,只能有一个参数可以使用“vararg”关键字修饰,一般放在最后一个参数。若不是最后一个参数,在使用时,其他的参数可以使用命名参数(Named Arguments)方式;或者函数有一个功能类型参数,可以在函数的后面定义一个Lambda表达式实现。
// vararg参数不是最后一个参数情况 fun asMultipleList(vararg ts: Int, multiple: Int): List<Int> { val resultL = ArrayList<Int>() for(data in ts) { resultL.add(data * multiple) } return resultL } // var multiList = asMultipleList(1, 2, 3, multiple=2) println(multiList) //后面更有功能类型参数 fun showInfo(vararg infos: String, show: (info: String) -> Unit) { for(info in infos) { show(info) } } // showInfo("info1", "info2") { println(it) }
调用一个“vararg”函数时,可以一个一个值使用,如“asList(1, 2, 3)”;也可以直接使用一个存在的数组数据,使用“*”关键字:
val a = arrayOf(1, 2, 3) val list = asList(-1, 0, *a, 4)
中缀表示法Infix和扩展函数
很多教程都是将Infix放在扩展函数前面,不合理,即使会Java也不方便理解,所以先学习扩展函数
所谓扩展函数就是扩展类的函数, 即 Extension Function , 可以在已有类中添加新的方法, 比继承更加简洁和优雅。在Kotlin中,允许对类进行扩展,不需要继承或使用 Decorator 模式,通过一种特殊形式的声明,来实现具体实现某一具体功能。扩展函数是静态解析的,并未对原类增添函数或者属性,也就是说对其本身没有丝毫影响。
扩展函数定义方式:
fun receiverType.functionName(params){ body}
receiverType:表示函数的接收者,也就是函数扩展的对象
functionName:扩展函数的名称
params:扩展函数的参数,可以为NULL
扩展函数并没有对原类做修改,而是为被扩展类的对象添加新的函数。
fun Int.add(vararg nums:Int):Int{ var result:Int=0 for (num in nums)result=result+num return result }
为Int声明了一个扩展函数add,用来计算多个数相加的结果,学习一定要灵活,将学到的东西灵活运用起来
使用方式:add(1,2,3)
或者 1.add(1)
在实际开发时,如果对一个类某一功能并不通用,只有某些特殊场景使用时,可以使用扩展函数,从而显得灵活多变。
之前说过,扩展函数是静态解析的,也就是,它并不是接收者类型的虚拟成员,意味着调用扩展函数时,调用扩展函数时,具体被调用的的是哪一个函数,由调用函数的的对象表达式来决定的,而不是动态的类型决定的。比如先声明了两个类Person和Teacher,其中teacher继承于Person,
在测试实例中,分别对Person和Teacher声明了扩展函数doFly(),又声明了fly()方法,其参数是一个Person对象,在其方法体内,调用了Person的扩展函数。现在测试实例中,创建了一个Teacher对象teacher,调用fly()方法并将teacher过去,实际上会调用哪个扩展函数呢?
open class Person {}class Teacher: Person() {}// 测试实例fun Person.doFly() { println("Person do fly")}fun Teacher.doFly() { println("Teacher do fly")}fun fly(person: Person) { person.doFly()}fun main(args: Array<String>) { var teacher: Teacher = Teacher() fly(teacher)}// LogPerson do fly
从Log打印中,可以清晰的看到的是,fly(teacher)调用的是Person的扩展函数。因为调用哪个函数, 仅仅是由参数person声明的类型决定, 这里参数person的类型为Person类.
现在我们了解了扩展函数,再来看中缀表达式infix
使用Infix需要满足以下三个条件:
1,它们是成员函数或扩展函数
2,他们有一个单一的参数
3,他们用infix关键字标记
例如刚刚写的add函数例子用中缀表达式就可以写为:1 add 2,增加了代码的美观性
功能范围
kotlin可以不需要像Java一样创建一个类来保存函数,直接在顶层写函数,除顶层函数之外,Kotlin函数也可以声明为本地函数,作为成员函数和扩展函数。
Kotlin支持本地函数,即另一个函数内的函数:
fun dfs(graph: Graph) { fun dfs(current: Vertex, visited: Set<Vertex>) { if (!visited.add(current)) return for (v in current.neighbors) dfs(v, visited) } dfs(graph.vertices[0], HashSet())}
本地函数可以访问外部函数的局部变量(即闭包),所以在上面的例子中,visited可以是局部变量:
fun dfs(graph: Graph) { val visited = HashSet<Vertex>() fun dfs(current: Vertex) { if (!visited.add(current)) return for (v in current.neighbors) dfs(v) } dfs(graph.vertices[0])}
成员函数是在类或对象内定义的函数:
class Sample() { fun foo() { print("Foo") }}
成员函数用点符号调用:Sample().foo()
通用函数
函数可以具有在函数名称前使用尖括号指定的泛型参数:
fun <T> singletonList(item: T): List<T> { // ...}
今天先学习到这里,我去吃饭先,明天学习内联函数,高阶函数和lambda表达式,尾递归函数
- Kotlin开发安卓APP笔记-函数和lambda表达式(2)
- Kotlin开发安卓APP笔记-函数和lambda表达式(1)
- 《转》Kotlin开发安卓APP笔记-函数和lambda表达式(3)
- Kotlin开发安卓APP笔记-类和对象(2)
- Kotlin开发安卓APP笔记-类和对象(1)
- Kotlin开发安卓APP笔记-数据类型
- Kotlin开发安卓APP笔记-接口
- Kotlin开发安卓APP笔记-协程(代替线程)
- Kotlin学习(十二): 函数、高级函数和Lambda表达式
- Kotlin学习笔记(九)函数,Lambda表达式
- Kotlin语法(十八)-高阶函数和Lambda表达式
- Kotlin中的函数和Lambda表达式
- Kotlin-22.Lambda表达式和函数
- Kotlin高阶函数和Lambda表达式
- Kotlin笔记(八)Lambda表达式
- Kotlin开发安卓APP笔记-条件语句和循环语句
- Kotlin开发安卓APP笔记实战-写个简易记事本(需求分析)
- Kotlin函数与Lambdas(二)--- 高阶函数和 lambda 表达式
- JAVA 23种设计模式对比总结
- windows系统mongodb配置服务及设置密码
- 01-eclipse打包运行程序总是报错java.lang.NoClassDefFoundError和ava.lang.ClassNotFoundException(打包原理)
- 无敌全的application.xml配置详解
- 如何在本地生产ssh key 然后上传的时候不用密码了
- Kotlin开发安卓APP笔记-函数和lambda表达式(2)
- 代码中的post和get的方法
- PDF免费转Word、PPT、Excel
- 编写一个C程序输入a,b,c三个值,输出其中的最大者 输入123顺序不一样结果不一样这是为什么??
- zabbix设置微信报警的配置过程
- ActiveMQ执行流程
- WebSocket的两种简单实现,Html5与STOMP。
- 3. MTK 底层耳机中断上报流程
- FFMPEG 播放时间计算 AVRational 音视频同步问题分析