栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Kotlin学习历程——函数与Lambda表达式(一)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Kotlin学习历程——函数与Lambda表达式(一)

Kotlin语言中文站

函数 基础写法

在Kotlin中使用关键字fun声明一个函数:

fun printInfo() {
    println("This is a function.")
}

如果携带参数呢?如下main函数所示:

fun main(args: Array) {
    println("length:${args.size}")
}

如果一个函数没有返回值,如上两个函数,那么它的返回值类型默认是Unit,可省略不写:

我们看看Unit的源码:

package kotlin


public object Unit {
    override fun toString() = "kotlin.Unit"
}

看注释是说对应Java中的void,那就没必要纠结了。

如果有返回值呢,那就在函数后面写明返回值类型:

fun getRandomNumber(range : Int) : Int {
    return Random.nextInt(range)
}



fun  getBean(t: T) : T {
    return t
}

如果函数的函数体可以由单个表达式(表达式表示有返回值)计算出来,也可以简写成如下形式:

//单个表达式可以计算出来
fun sum(a: Int, b: Int) : Int{
    return a + b
}
//可以简写成如下形式, 它和上面的写法是等价的,不过更加简单明了
fun sum(a: Int, b: Int) : Int = a + b



//单个表达式可以计算出来
fun max(a:Int, b:Int) : Int {
    if(a > b) {
        return a
    }
    return b
}

//max
fun largeNumber(a:Int, b:Int) : Int = if(a > b) a else b

默认参数

Kotlin中函数可以有默认值,当省略相应的参数时就会使用默认值;相对Java而言,它可以减少一大堆重载函数。我们来看一个案例:

Android中EventBus库大家应该都不陌生,在很多业务场景下能实现代码逻辑解耦。如下是EventBus的一个消息事件类。

public final class IMessageEvent {
    
    
    public String msg_what;
    public String arg1;
    public String arg2;
    public int arg3;
    public int arg4;

    public BeBOMessageEvent(String msg_what) {
        this.msg_what = msg_what;
    }

    public BeBOMessageEvent(String msg_what, int arg3) {
        this.msg_what = msg_what;
        this.arg3 = arg3;
    }

    public BeBOMessageEvent(String msg_what, String arg1) {
        this.msg_what = msg_what;
        this.arg1 = arg1;
    }

    public BeBOMessageEvent(String msg_what, String arg1, int arg3) {
        this.msg_what = msg_what;
        this.arg1 = arg1;
        this.arg3 = arg3;
    }

    public BeBOMessageEvent(String msg_what, String arg1, String arg2, int arg3) {
        this.msg_what = msg_what;
        this.arg1 = arg1;
        this.arg2 = arg2;
        this.arg3 = arg3;
    }
}

可以发现重载的构造函数比较多。 如果用Kotlin来写,将会快捷很多:

class IMessageEvent(var msg_what: String, var arg1: String = "", var arg2: String = "", var arg3: Int = 0, var arg4: Int = 0) {
    companion object {
        val ENABLE_DEBUG_MODE = "ENABLE_DEBUG_MODE"
    }
}

使用如下:

//1个参数,其他全部用默认值
val messageEvent = IMessageEvent(IMessageEvent.ENABLE_DEBUG_MODE)
//2个参数,其他用默认值
val messageEvent1 = IMessageEvent(IMessageEvent.ENABLE_DEBUG_MODE, "A0001")
//或者这样(只传递首尾参数)
val messageEvent2 = IMessageEvent(IMessageEvent.ENABLE_DEBUG_MODE, "A0001", "", 0, 50)

默认参数在某些场景下(一个默认参数在一个无默认值的参数之前),使用上会产生歧义,导致编译报错:

fun printInfo(tag: String = "hepingdev##", info: String) {
    println("$tag$info")
}

调用如上函数:

看错误提示是因为没有传递参数值info,所以这就为难了(我是想第一个参数使用默认值,只传递第二个参数)。

具名参数

在kotlin中使用具名参数解决这类问题:

fun main(args: Array) {
    printInfo(info = "函数")
}

也就是指明给哪个参数赋值,如上指明给info参数赋值。


可变数量的参数(vararg)

当方法的参数数据类型已经确定,但是参数的个数不确定,就可以使用可变数量的参数。 如下代码所示:

fun  mutableListOf(vararg elements: T): List {
    val result = ArrayList()
    for (t in elements) // elements is an Array
        result.add(t)
    return result
}

我们调用上面mutableListOf函数时,常见场景如:

  • 一个一个的传递参数
fun main(args: Array) {
    //一个一个的传递参数
    var list = mutableListOf("1", "2", "3")
}
  • 将一个数组的内容传递给该函数,使用展开操作符(在数组前面加*)
//传递一个数组的内容
var aList = arrayOf("1","2","3")
var concatList = mutableListOf("23234", *aList, "w3r")
println(concatList)  //打印:[23234, 1, 2, 3, w3r]

它类似JavaScript里面的展开操作符(…),只是写法不一样。


同样,如果vararg参数不是列表中最后一个参数,就需要使用具名参数传递其后的参数值。如下:

fun  subList(vararg elements: T, endIndex: Int): List? {
    if(elements.isEmpty() || endIndex == 0) return null
    val result = ArrayList()
    for (e in elements) {
        result.add(e)
        if(result.size - 1 >= endIndex) {
            break
        }
    }
    return result
}


//调用
fun main(args: Array) {
    var aList = listOf("1","2","3")
    //具名参数endIndex
    subList(aList, endIndex = 1)
}
中缀函数

如下代码中until即中缀函数,调用中缀函数不需要调用的点和圆括号。

for (i in 1 until 5){
    println("$i")  //1,2,3,4
}

声明一个中缀函数必须满足以下要求:

  • 必须是成员函数(对象的方法)或扩展函数。
  • 必须只有一个参数,且参数不得是可变数量的参数,同时不能有默认值。
  • 必须采用infix关键字修饰。

按照上面的要求,我们简单声明两个中缀函数看看,如下:

class InfixFunction {
    infix fun printInfo(onlyParams : String) {
        println(onlyParams)
    }
}


fun main(args: Array) {
    val mInfixFunction = InfixFunction()
    mInfixFunction printInfo "打印这个值"     //打印这个值
}





infix fun Int.add_(b : Int) : Int = this + b


fun main(args: Array) {
    val a = 1
    val c = a add_ 2
    println(c)  //3
}

很“高大尚”的一种语法糖,是不是很有意思呢。


上一篇:Kotlin学习历程——对象声明与伴生对象

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/925121.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号