Kotlin函数运用

  1. 函数的基本用法
    一段相对独立的代码块通过大括号包起来,再给这个代码块取个名字,便形成了函数的雏形。
    //java表达式:修饰词  返回类型  函数名(){}
    public void getDinnerVoid(){
    
    }
    //kotlin表达式:修饰词  fun关键字  函数名():返回类型{}
    public fun getDinnerVoid():Unit{
    
    }
    //kotlin 默认就是public可省略,单返回值是空即Unit (viod)也看省略
    fun getDinnerVoid(){
    
    }

    看了这些代码是不是对kotlin的函数了解了一些,现在让我们来看看函数的输出参数和输入参数类型

    //void 省略 没输入参数,也没输出参数
        fun getDinnerEmpty(){
    
        }
        //只有输入参数 不可null
        fun getDinnerInput(egg:String){
    
        }
        //只有输入参数 可null
        fun getDinnerCanNull(egg: String?){
    
        }
        //返回值为void
        public fun getDinnerVoid():Unit{
    
        }
        //返回值为String
        fun getDinnerString(egg:String):String{
            return "";
        }
        //默认参数
        fun getDinnerStr(egg:String="wwww"):String{
            return egg;
        }
        //参数个数不确定
        fun getDinnerStr(egg:String,vararg other:String?):String{
            return egg;
        }

    由上面代码可知kotlin还增加了一些新功能,让我们看看怎么调用
    以默认参数和不确定个数参数为例

    //默认参数可以替换掉,也可以不替换
    val s2=getDinnerStr(egg = "eee")
    val s2=getDinnerStr()
    //除了"ss"其他都是不确定参数
    val s1 = getDinnerStr("ss","sdf","dfs","eee")

    *我们知道kotlin和java是 可互操作但java中没有这些新增功能这样调用会报错,只要我们加一个"@JvmOverloads"

    @JvmOverloads
    fun  getDinnerStr(egg:String="wwww"):String{
          return egg;
    }
    -----------------------------------------------------------------------------
    java中调用
    String str = new getDinnerStr()
  2. 特殊函数
    泛型函数:按照之前的例子,函数的输入类型在定义参数时就要指定,可是有时候参数类型是不确定的,只有在调用是才知道具体类型像List一样
    fun <T> appendString (tag : String , vararg otherInfo :T?):String{
        var str = tag;
        for(item in otherInfo){
            str = "$str${item.toString()}";
        }
        return str;
    }    
    //调用
    appendString<Int>("数字",1,2,3,4,5)
    appendString<String>("字符串","一","二","三","四","五")

    定义泛型函数时得再函数名称前面添加"<T>",表示以T声明的参数(包括输入参数和输出参数),其参数必须在函数时调用指定。

    内联函数:fun前面添加关键词"inline"的函数叫做内联函数,内联函数在调用时会在调用处的代码直接复制一份,调用10次就复制10份,而非普通函数仅仅提供一个访问地址。
    //内联函数
    inline fun <reified T : Number> setArrayStr(array:Array<T>) {
    
    }

     该函数属于泛型函数兼内联函数,该参数基类泛化,凡是继承自该基类的子类,都可以作为输入参数进行函数调用,该函数只有被在内联函数才能被具体化。

    *泛型约束

    我们可以使用泛型约束来设定一个给定参数允许使用的类型。

    Kotlin 中使用 : 对泛型的类型上限进行约束。

    最常见的约束是上界(upper bound):

    fun <T : Comparable<T>> sort(list: List<T>) {
        // ……
    }

    Comparable 的子类型可以替代 T。 例如:

    sort(listOf(1, 2, 3)) // OK。Int 是 Comparable<Int> 的子类型
    sort(listOf(HashMap<Int, String>())) // 错误:HashMap<Int, String> 不是 Comparable<HashMap<Int, String>> 的子类型

    默认的上界是 Any?。

    对于多个上界约束条件,可以用 where 子句:

    fun <T> copyWhenGreater(list: List<T>, threshold: T): List<String>
        where T : CharSequence,
              T : Comparable<T> {
        return list.filter { it > threshold }.map { it.toString() }
    }

    递归函数:fun前面添加关键词"tailrec"的函数叫做内联函数,该函数适用于函数尾部递归调用自身,此时编译器会自动优化递归,即循环方式代替递归,从而避免栈溢出的情况。

    tailrec fun fac(n:Int):Int{
            return if (n<=1) n else n*fac(n-1);
        }

    高阶函数

     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;
        }
    maxCustom(str) { a, c->a.length>c.length}
    maxCustom(str,{a,c->a>c})

    允许将函数表达式作为输入参数传进来,就形成了高阶函数,这里的greater函数就像是个变量greater函数有两个输入参数,返回布尔型的输出参数如果第一个参数大于第二 个参数,就认为greater返回true, 否则返回false
    扩展函数:给系统类补写新方法

    fun Date.getNowData():String{
        val sdf = SimpleDateFormat("yyyy-MM-dd")
        return sdf.format(this)
    }

     

posted @ 2020-09-08 18:39  勤奋的小铁  阅读(170)  评论(0编辑  收藏  举报