kotlin教程4:函数进阶

这篇具有很好参考价值的文章主要介绍了kotlin教程4:函数进阶。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

kotlin教程:编程基础💎数据结构💎面向对象

可变参数

kotlin的函数定义非常灵活,既可以按照顺序传参,也可以通过参数名传参,而且可以设置参数默认值,这些在基础教程中已经讲过了。

此外,kotlin中用vararg修饰的参数,为长度可变的参数列表

fun printLst(vararg ts: Int){
    for(t in ts){
        println(t)
    }
}

printLst(1,2,3)
/*
1
2
3
*/

尾递归函数

递归是一种常用的编程技巧,就像之前写的递归式阶乘

fun fac(n:Int):Int{return if(n>1) n*fac(n-1) else 1}

但递归有一个很重要的缺点,即每次调用都要在栈中保存上一个函数的返回地址,如果递归层数太多,会导致栈溢出,所以很多时候会将递归算法改写成动态规划。

为了解决递归问题,kotlin提供了尾递归方案,即通过tailrec修饰的函数,如果在函数的最后一行调用自身,那么编译器将自动将递归函数转成迭代形式,而无需担心堆栈错误。

为了理解什么是尾递归,下面以斐波那契数列举个例子

fun fib(n:Int):Int{
    if(n<3)
        return 1
    else
        return fib(n-1)+fib(n-2)
}
fun main(){
    println(fib(215))
}

这个函数尽管在最后一行调用了自身,但调用自身后还有一个相加的操作,所以是不符合尾递归的要求的。

对此可将其改写为

fun fib(n:Long, a: Long, b: Long): Long {
    if (n < 1) return a
    else return fib(n-1, b, a + b)
}

这就是尾递归的形式。对比这两种不同的递归方案可以发现,第一种运行之后会卡住,在短时间内没法得出结果,后者则轻而易举地得出了。

>kotlin test.jar
319982248

当然,这个过程并没有使用tailrec关键字,所以当n的值比较大的时候一样会出问题

fun main(){
    println(fib(12000, 1, 1))
}

会报这个错误

Exception in thread "main" java.lang.StackOverflowError
        at TestKt.fib(test.kt:3)

下面可测试一下编译优化的效果

tailrec fun fib(n:Long, a: Long, b: Long): Long {
    if (n < 1) return a
    else return fib(n-1, b, a + b)
}

fun main(){
    println(fib(12000, 1, 1))
}

编译运行,顺利得出结果

>kotlin test.jar
3221758877563775297

函数式

所谓函数式,从敲代码的角度出发,就是把函数作为一种数据类型,可以自由地作为其他函数的参数与返回值。

由于Kotlin中,函数中所有的参数和返回值都要声明数据类型,所以,函数在作为参数传递时,也要标明函数的输入输出返回值,例如下面代码是函数作为参数的一个例子

fun testFunc(func:(Int)->Int) : (Double)->Double{
    return {a:Double -> func(a.toInt()).toDouble()}
}

fun test1(func:(Int)->Int):Int{
    return func(5)
}

其中,func:(Int)->Int为输入参数,func为参数名,(Int)->Intfunc作为一种函数的输入输出声明,表示func是一个输入Int输出Int的函数。

(Double)->DoubletestFunc的返回值类型,表示一个输入Double输出Double函数。

换言之testFunc的功能是,将一个输入输出均为整型的函数,转化为输入输出均为浮点型的函数。

return{ -> }是一个匿名函数,这个在最开始介绍函数的时候就已经讲过了。

接下来测试一下,先新建一个输入整型输出整型的函数

fun square(a:Int):Int{return a*a}
square(3)   // 返回值 kotlin.Int = 9
square(3.0) //报错

然后转换,需要注意,当函数作为参数传递时,需要用::标识

testFunc(::square)(3.0) //返回值9.0

也可以新建一个函数文章来源地址https://www.toymoban.com/news/detail-445677.html

val dSquare = testFunc(::square)
dSquare(3.0)    //kotlin.Double = 9.0

到了这里,关于kotlin教程4:函数进阶的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【28】Kotlin语法进阶——使用协程编写高效的并发程序

    提示:此文章仅作为本人记录日常学习使用,若有存在错误或者不严谨得地方欢迎指正。 协程是Kotlin语言中很有代表性的一种并发设计模式,用于简化异步执行的代码。 协程和线程有点类似,可以简单地将它理解成一种轻量级的线程 。我们前面学习的线程是属于重量级的,

    2024年02月03日
    浏览(37)
  • Kotlin学习 - 高阶函数和内联函数

    高阶函数定义 如果一个函数接收另一个函数作为参数,或者返回值的类型是另一个函数,那么该函数就称为高阶函数。 以前开发的时候,入参或返回值都是基本类型或者对象,但是在Kotlin中出现了一个新的类型:函数类型。就是函数也可以像 String 这种类型一样做入参或者返

    2024年02月12日
    浏览(51)
  • Spring Boot进阶(79):使用Kotlin轻松打造高效的Spring Boot应用

            随着Java开发语言的发展,很多新的编程语言不断涌现,其中Kotlin备受开发者青睐,它是一种相对新的基于JVM的静态语言,支持Java虚拟机(JVM)和Android开发。Kotlin将Java语言中的一些缺点进行了优化,并增加了很多新的特性,因此在开发效率和代码可读性上具有很

    2024年02月08日
    浏览(38)
  • 【Kotlin】探索回调机制:函数类型、高阶函数和接口

    当在 Kotlin 中开发应用程序时,经常会遇到需要使用回调机制的情况。回调是一种常见的编程模式,用于在异步操作完成后通知调用方,并处理相应的结果或事件。在 Kotlin 中,有几种不同的方法可以实现回调,包括使用函数类型、高阶函数和接口。每种方法都有其优点和适用

    2024年02月02日
    浏览(38)
  • kotlin 的函数参数

    https://blog.csdn.net/yoonerloop/article/details/123241451 一、无参数的函数参数 1、回调 //定义 interface OnClickListener {     fun onClick() }   private fun setOnClickListener(listener: OnClickListener) {   }   //使用 setOnClickListener(object : OnClickListener {     override fun onClick() {       } }) 2、闭包 //定义 private f

    2024年02月14日
    浏览(29)
  • Kotlin函数和对象

    1.高阶函数 如果一个函数的参数是函数类型或者返回值是函数类型,那么这个函数就是高阶函数。 在kotlin中函数也是有类型的,跟整型、字符串类型是同样的性质,函数类型就是将函数的“输入参数类型”和“返回值类型”的抽象表达,如(Int,Int)- Int 2.扩展函数 kotlin允许

    2024年02月20日
    浏览(34)
  • Kotlin理解内置函数

    Kotlin 内置函数包括: let 、 run 、 with 、 apply 、 also ,这些函数都是在 Any 类中定义的扩展函数,所以任何对象都可以调用这些函数。 apply 是 Kotlin 标准库中的一个函数,它允许您在调用对象的上下文中执行一系列操作,并返回该对象本身。这在构建对象的过程中非常有用,

    2024年02月13日
    浏览(29)
  • kotlin高阶函数

    函数式API:一个函数的入参数为Lambda表达式的函数就是函数式api 例子: 上面这段函数: 首先这个函数是一个泛型函数 泛型函数的定义:就是我们在写完一个函数后,只知道一个总的类型,而这个总的类型下有很多继承了这个总类型的类,在返回时我们不知道这个函数具体返回哪个子

    2024年02月15日
    浏览(43)
  • Kotlin 高阶函数详解

    在 Kotlin 中,函数是一等公民,高阶函数是 Kotlin 的一大难点,如果高阶函数不懂的话,那么要学习 Kotlin 中的协程、阅读 Kotlin 的源码是非常难的,因为源码中有太多高阶函数了。 高阶函数的定义非常简单: 一个函数如果参数类型是函数或者返回值类型是函数,那么这就是一

    2024年02月11日
    浏览(28)
  • Kotlin 内联函数

    在JVM中每次函数调用,都会进行 操作栈 操作(栈帧),会增加内存使用和开销。 另外传入的 lambda 函数 参数,也会 内存分配(创建类和对象)。 inline 使用 内联 (inline) 可以避免上面的开销,通过把 函数的代码 直接插入 调用处, 而不是 调用函数 和 创建 lambda 函数类和

    2024年01月19日
    浏览(27)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包