kotlin汇总6-函数
来源:互联网 发布:centos 7 hadoop 集群 编辑:程序博客网 时间:2024/06/03 17:28
1.基础知识
函数声明使用fun关键字
fun double(x: Int): Int {}
函数调用
val result = double(2) //调用普通函数Sample().foo() // create instance of class Sample and calls foo//调用类成员函数
使用infix标记
// Define extension to Intinfix fun Int.shl(x: Int): Int {...}1 shl 2 等同于 1.shl(2)
函数的参数定义
fun powerOf(number: Int, exponent: Int) {...}
给参数默认值
fun read(b: Array<Byte>, off: Int = 0, len: Int = b.size()) {...}
给参数命名(调用时使用的名称)
fun reformat(str: String, normalizeCase: Boolean = true, upperCaseFirstLetter: Boolean = true, divideByCamelHumps: Boolean = false, wordSeparator: Char = ' ') {...}reformat(str) 等同于 reformat(str, true, true, false, '_')//也可以下面这样调用reformat(str, wordSeparator = '_')//增加代码的可读性
返回Unit的函数,如果一个函数返回的是无用的,那么可以用Unit作为返回值
fun printHello(name: String?): Unit { if (name != null) println("Hello ${name}") else println("Hi there!") // `return Unit` or `return` is optional}
Unit可以被推断,所以也可以忽略
fun printHello(name: String?) { ...}
函数也可以写成一行
fun double(x: Int): Int = x * 2//因为Int可以被推断,所以也可以省略fun double(x: Int) = x * 2
函数的可变参数,可以用vararg修饰
fun <T> asList(vararg ts: T): List<T> { val result = ArrayList<T>() for (t in ts) // ts is an Array result.add(t) return result}//调用如下val list = asList(1, 2, 3)
注意:可变参数和Java一样,只可以修饰一个参数,而且必须是最后的。
2.函数作用范围
2.1 本地函数
在kotlin中,函数可以定义在top-level,不需要创建一个class来使用函数
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())}
2.2 成员函数
class Sample() { fun foo() { print("Foo") }}//调用如下Sample().foo() // creates instance of class Sample and calls foo
2.3泛型函数
fun <T> singletonList(item: T): List<T> { // ...}
2.4扩展函数
之前的有介绍过。
2.5 高阶函数和lambda函数
fun <T> lock(lock: Lock, body: () -> T): T { lock.lock() try { return body() } finally { lock.unlock() }}//调用如下fun toBeSynchronized() = sharedResource.operation()val result = lock(lock, ::toBeSynchronized)//使用lambdaval result = lock(lock, { sharedResource.operation() })//把表达式移除来lock (lock) { sharedResource.operation() }
看另外一个典型的例子
fun <T, R> List<T>.map(transform: (T) -> R): List<R> { val result = arrayListOf<R>() for (item in this) result.add(transform(item)) return result}//调用如下List<Int> ints = ...val doubled = ints.map { value -> value * 2 }//可以使用it来代替val doubled = ints.map { it * 2 }//使用LINQ方式strings.filter { it.length == 5 }.sortBy { it }.map { it.toUpperCase() }
2.6内联函数
因为使用高阶函数,每个函数都有个闭包,内存的分配和虚拟的调用都会带来运行时开销。通过内联lambda表达式可以减少这方面的开销。
lock(l) { foo() }
lock函数可以在调用的地方很容易被内联,内联lock函数之后,可以避免为参数foo()创建一个函数对象而自动 生成一个调用,编译器会使用如下代码
l.lock()try { foo()}finally { l.unlock()}
上面这种方式是不是我们一开始就想要的这种!怎么内联lock函数呢
inline fun lock<T>(lock: Lock, body: () -> T): T { // ...}
inline默认会函数本身和lambda表达式,可以对参数使用noinline
inline fun foo(inlined: () -> Unit, noinline notInlined: () -> Unit) { // ...}
注意下面的区别:
fun foo() { ordinaryFunction { return // ERROR: can not make `foo` return here }}fun foo() { inlineFunction { return // OK: the lambda is inlined }}
注意下面
inline fun f(crossinline body: () -> Unit) {
val f = object: Runnable {
override fun run() = body() //只有使用crossinline才可以在内部里调用lambda表达式
}
// …
}
使用Reified的具体类型参数
假如我们有如下代码:
fun <T> TreeNode.findParentOfType(clazz: Class<T>): T? { var p = parent while (p != null && !clazz.isInstance(p)) { p = p.parent } @Suppress("UNCHECKED_CAST") return p as T?}
调用方式:
treeNode.findParentOfType(MyTreeNode::class.java)
是不是感觉很复杂。。。可能你想下面这样调用
treeNode.findParentOfType<MyTreeNode>()
所以你需要重新定义函数如下:
inline fun <reified T> TreeNode.findParentOfType(): T? { var p = parent while (p != null && p !is T) { p = p.parent } return p as T?}
你也可以下面这样
inline fun <reified T> membersOf() = T::class.membersfun main(s: Array<String>) { println(membersOf<StringBuilder>().joinToString("\n"))}
属性也可以被内联
val foo: Foo inline get() = Foo()var bar: Bar get() = ... inline set(v) { ... }//也可以对整个属性内联inline var bar: Bar get() = ... set(v) { ... }
2.7尾部递归函数(Tail recursive functions)
使用tailrec修饰,下面两段代码等同,可以自己理解下。
tailrec fun findFixPoint(x: Double = 1.0): Double = if (x == Math.cos(x)) x else findFixPoint(Math.cos(x))
private fun findFixPoint(): Double { var x = 1.0 while (true) { val y = Math.cos(x) if (x == y) return y x = y }}
- kotlin汇总6-函数
- Kotlin 函数
- Kotlin-函数
- Kotlin -- 函数
- Kotlin-函数
- Kotlin函数
- Kotlin学习资料汇总
- Kotlin汇总1
- Kotlin汇总4-泛型
- kotlin汇总7-Coroutines
- Kotlin的学习汇总
- kotlin汇总10-Java调用kotlin
- Kotlin语言学习资源汇总
- kotlin项目推荐 资料汇总
- kotlin汇总8-其他1
- kotlin汇总8-其他2
- Kotlin学习之函数
- Kotlin构造函数
- 用IPTABLES的端口转发功能实现访问位于内网的MYSQL服务器
- Linux 链接库编译与多重依赖
- AM335x DDR3配置
- WebRtcVideoSendStream和VideoSendStream的创建
- 深度学习笔记(待续)
- kotlin汇总6-函数
- InteliJ IDEA上传项目到GitHub
- android 6.0权限--代码
- Android线程与线程池
- 经典算法之交换排序(冒泡排序、快速排序)
- oracle中rownum的用法,查询某个区间的数据
- vivado如何实现增量编译,加快布局布线
- 51Nod-1013 3的幂的和【快速模幂+逆元】
- ByteBuffer用法小结