Kotlin的几种特殊函数

一 泛型函数

函数的参数类型一般在函数定义的时候就规定了的,但是如果在使用的时候才能确定具体使用什么参数类型,这个要如何解决呢?泛型函数解决这个问题

定义泛型函数时,要在函数名之前加上这个符号,表明声明T类型的参数,具体确认在函数使用中给泛型T赋予确切值既可

fun <T> fanxing(tag:String,vararg args:T):T?{

    var a : T? = null
    for (item in args){
        a = item
        Log.d("fanxing","$tag : $item")
    }
    return  a
}

二 内联函数

举个例子,如果我们想接受泛型类型下的子类,比如number泛型类型,想接受它的子类:Int,double,Float类型,此时再用下面的泛型函数只能接受number类型

fun  fanxing(tag:String,vararg args:Number):Number?{

    var a : T? = null
    for (item in args){
        a = item
        Log.d("fanxing","$tag : $item")
    }
    return  a
}

如果想接受其子类类型,就要用到内联函数

inline fun <reified T : Number> fanxing(tag:String,vararg args:Number):Number?{

    var a : T? = null
    for (item in args){
        a = item
        Log.d("fanxing","$tag : $item")
    }
    return  a
}

内联函数在编译的时候,会在调用处把该函数的内部代码直接复制一份,调用几次就复制几次,而非普通函数那样仅仅是提供一个函数地址

三 高阶函数

上面说的函数的入参都是对象类型,而高阶函数可以传入其他的函数作为入参;熟练使用高阶函数,可以达到让你意想不到的效果。
比如:对于一个数组变量,如果我们想获得这个数组变量的最大值,我们可以调用这个数组变量的max()方法,但是如果这个数组变量是字符串数组,比如arrayOf(“How”, “do”, “you”,“do”, "I’m ", “Fine”),此时调用max函数得到的并不是字符长度最长的那个字符,而是在字母表最靠后的那个字符串(you)。当然我们也可以重新写一个函数,改变其算法,但是如果我们那天需要其他比较大小的算法,难道又要再写一个函数?所以Kotlin就有一个高阶函数,直接把比较函数作为参数传入,由开发者再调用高阶函数的时候来选择具体的算法函数传入即可

fun <T> maxCustom(array:Array<T>,greater:(T:T) ->Boolean):T?{

    var max : T? = null
    for (item in array){
       if(max == null || greater(item,max) ){
		max = item
		}
    }
    return  max
}

var string_array:Array<String> = arrayOf("How", "do", "you", "do", "I'm ", "Fine")

maxCustom(string_array,
//比较值的大小
{
a,b -> a>b
});

var string_array:Array<String> = arrayOf("How", "do", "you", "do", "I'm ", "Fine")

maxCustom(string_array,
//比较长度的大小
{
a,b -> a.length>b.length
});

这里传入的函数用{ }包起来,这里用到了Lambda的匿名函数的写法;此时利用高阶函数,我们可以选择性的选择不同算法函数传入,达到效果

四 扩展函数

使用java开发的时候,虽然系统自带的类提供了很多方法,但是还是无法满足所有的业务要求,此时就要写一个个工具类,这样会使工具类越来越多,越来越难以管理。此时kotlin就推出了扩展函数。扩展函数是让开发者给系统api提供补写的机会;比如数组工具类里有比较大小的max()和排序的sort(),但是没有交换的方法,此时可以用扩展函数给数组工具类加入排序的功能函数

fun Array<Int>.swap(pos1: Int, pos2: Int) {
 val tmp = this[pos1] //this表示数组变量自身
 this[pos1] = this[pos2]
 this[pos2] = tmp
}

但是这只是针对Int数组类型的工具类,如果要满足所有类型的,此时就要需要引入上面说过的泛型函数的概念

fun <T> Array<T>.swap(pos1: Int, pos2: Int) {
 val tmp = this[pos1] //this表示数组变量自身
 this[pos1] = this[pos2]
 this[pos2] = tmp
}

有了扩展函数,数组变量就可以直接调用新增的swap方法,仿佛是系统自带的函数一样,一下是swap函数的使用案例:

val array:Array<Double> = arrayOf(1.0, 2.0, 3.0, 4.0, 5.0)
btn_function_extend.setOnClickListener {
 //下标0,3的数组元素交换
 array.swap(0, 3)
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值