函数

来源:互联网 发布:网络不良色情举报中心 编辑:程序博客网 时间:2024/06/06 00:29

1、函数

函数(方法)使用fun关键字来定义

fun test(param: String) {
}

fun test(x: Int, y: Int) : Int {
     return x + y
}

使用等式替代括号

fun test(x: Int, y: Int): Int = x + y

如何写默认值

fun test(x: Int, y: Int = 4): Int = x +y
当你这么写的时候,表示你调用该方法,第二个参数是可选的
test(1)的结果是5
test(1, 2)的结果是3

2、Infix

先看写法:

infix fun Int.plus(x: Int): Int {
    return this + x
}
调用的时候,你可以写1.plus(2),也可以利用infix的特性写成1 plus 2
使用infix需要注意几点:
  • 成员函数或者扩展函数
  • 单入参函数
  • 关键字infix

3Parameters

Kotlin中的函数参数写法都是 name:Type,并且可以在括号中赋初始值。有趣的是,如果你不想传递没有必要的参数,在赋初始值后,你可以不传递。

4有返回值

funprintHello(name:String?):Unit{ 
    if(name!=null) 
        println("Hello ${name}”) 
    else 
        println("Hi there!”) 
    // `return Unit` or `return` is optional
}

fundouble(x:Int):Int  =  x* 2


5Varargs数量可变的入参


fun <T> asList(test: String,vararg ts:T): List<T> {
    val result = ArrayList<T>()
    for (t in ts)// ts is an Array
        result.add(t)
    return result
}
一个函数的入参,最后一个,可以标记varargs,允许可变数量的入参。asList(1, 2, 3)

6、函数的范围

Kotlin中的函数可以写在文件的顶级,也就是说可以在不创建类的情况下去调用方法。也可以作为本地的函数。
Kotlin支持函数嵌套
funtest1() {
    fun test2() {
       
    }
    test2()
}
当然还有类的成员函数,需要创建类才能调用。


7、范型函数

函数可以有范型参数。


8、Inline函数

使用高阶函数会带来一些运行时的坏处:每个函数是一个对象,捕获闭包(captures a closure),函数体里面的变量都可以被调用。内存分配(函数对象和类)以及虚拟调用(virtual calls)会引入运行时间开销。
但是,看起来再许多案例中,这种开销通过内联化lambda表达式能够被完全避免。

考虑下面的情况:
lock(l) { foo() }
编译器没有为参数创建一个函数对象并生成一个调用。取而代之,编译器可以生成以下代码:
l.lock()try {    foo()}finally {    l.unlock()}
这个不是我们从一开始就想要的吗?
为了让编译器这么做,我们需要使用 inline 修饰符标记 lock()函数:
inline fun lock<T>(lock: Lock, body: () -> T): T {    // ……}
inline 修饰符影响函数本身和传给它的 lambda 表达式:所有这些都将内联到调用处。
在java中我们不能直接去申明内联函数,因此这个概念比较模糊。内联可能导致生成的代码增加,但是如果我们使用得当(不内联大函数),它将在性能上有所提升,尤其是在循环中的“超多态(megamorphic)”调用处。

如果你只想被(作为参数)传给一个内敛函数的lambda表达式中有一些被内联,你可以用noinline修饰符标记一些函数参数。可以内联的lambda表达式只能在内联函数内部调用或者作为可内联的参数传递,但是noinline可以以任何方式操作,比如存储在字段中,传送等。

⚠️如果一个内联函数没有可内联的函数参数,并且没有具体化的类型参数,编译器会产生警告,因为内联这样的函数很可能没有益处。

9、扩展函数

参考Anko


10Higher-Order Functions and Lambdas

高阶函数可以将函数作为入参,或者作为返回值。
fun<T> lock(lock: String, body: () ->T):T{
    lock.toString()
    return body()
}

valresult =lock("lock", ::toBeSynchronized)
val result1 =lock("lock",{ test1()})
valresult2 =lock("lock"){test1()}

使用it关键字,当函数只有一个入参的时候,可以这么用。了解下map()这个高阶函数
list.map{ x-> x +2 }
list.map{ it *2}
list.map{if (it /2 ==0) (it *2)else (it +2)}

11Tail recursive functions

尾递归函数,在函数前面加上tailrec修饰符,允许用循环写的算法改用递归函数,而没有堆栈溢出的风险。并且相比传统的写法更加的简单。
tailrec funfindFixPoint(x: Double =1.0): Double
        =if(x == Math.cos(x)) x elsefindFixPoint(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
    }
}
原创粉丝点击