美文网首页
Kevin Learn Kotlin:函数

Kevin Learn Kotlin:函数

作者: Kevin_小飞象 | 来源:发表于2021-12-02 09:24 被阅读0次
    每日一图.jpg

    Kotlin 的函数

    1. 方法声明

    16.png
    • 普通类的方法
      实现一个普通类,可以借助关键字 class 来创建一个普通类。
    /**
     * Created on 2021/11/26 13:48
     *
     * @author Gong Youqiang
     */
    
    fun main() {
        val person = Person()
        person.name = "Kevin"
        person.age = 20
    
        person.eat()
    }
    
    class Person {
        var name = ""
        var age = 0
    
        fun eat() {
            println(name + "is eating. He is " + age + " years old.")
        }
    }
    
    • 静态类的方法
      实现一个静态类(如工具类),可以借助关键字 object 来创建一个静态类。
    fun main() {
        println(NumUtils.double(3))   // 6
    }
    
    object NumUtils {
        fun double(num : Int) : Int {
            return num * 2
        }
    }
    
    • 伴生类的方法
      实现一个静态方法,可以借助关键字 companion object 来实现普通类的静态方法。
    fun main() {
        Person.eat("Kevin",20)
    }
    
    class Person {
        companion object{
            fun eat(name: String,age:Int) {
                println(name + "is eating. He is " + age + " years old.")
            }
        }
    }
    

    2. 方法参数

    • 默认参数
      方法参数可以有默认值,当省略相应的参数时使用默认值。
    fun main() {
        // 默认参数调用
        show(20,300)
    }
    
    fun show(offset:Int = 10,start:Int){
        println("show:${offset},${start}")
    }
    
    • 具名参数
      如果一个默认参数在一个无默认值的参数之前,那么无默认值的参数,只能通过使用具名参数调用该方法来使用:
    fun main() {
        //具名参数调用
        show(start = 150)
    }
    
    fun show(offset:Int = 10,start:Int){
        println("show:${offset},${start}")
    }
    

    如果最后一个参数是方法,那么它既可以作为具名参数在括号内传入,也可在括号外传入:

    fun main() {
        // 括号内
        show(20,300,action = {
            // 方法体里面的最后一行,就是该方法的返回值
            val a = 8
            val b = 2
            a + b
        })
    
        // 括号外
        show(start = 100){
            val a = 3
            val b = 4
            a * b
        }
    }
    
    fun show(offset:Int = 10,start:Int,action:()->Int){
        println("show:${offset},${start}")
        println(action())
    }
    

    说明:
    a. offset:Int = 10 表示该参数有一个默认值是 10;
    b. start: Int 表示该参数没有默认值
    c. 第三个参数是一个方法,参数名叫 action:()
    d. 方法参数的返回值使用 -> Int

    • 可变数量的参数
      方法的参数(通常是最后一个)可以用关键字 vararg 修饰:
    fun main() {
        val add = add('A', 'B', 'C')
        println("result:${add}")
    }
    
    fun add(vararg str: Char): String{
        val result = StringBuffer()
        for (char in str) {
            result.append(char)
        }
        return result.toString()
    }
    

    3. 顶层函数和属性

    在 Java 中,所有的代码都需要写作类的函数,但是在项目中,很多代码并不能归属到类中,这时候我们一般会定义一个 xxUtils 类,并在其中声明 static 的静态方法。

    在 kotlin 中,我们可以把这些函数直接放到代码文件的顶层,不用从属于任何的类,这些放在文件顶层的函数仍然是包内的成员,如果你需要从包外访问它,则需要 import ,但不再需要额外包一层。

    3.1 在 Java 中调用顶层函数

    如果我们想要在 Java 中调用这些顶层函数,则需要通过 Kotlin 根据包含函数的文件的名称生成的类:

    • KotlinMethod.kt
    fun kotlinFunc() {}
    
    • JavaCallKotlin.java
    public class JavaCallKotlin {
        public JavaCallKotlin() {
            KotlinMethodKt.kotlinFunc();
        }
    }
    

    前者包含一个顶层函数,那么在 Java 中,就会根据该文件名生成一个 {文件名}Kt 的类型,再通过这个类来调用这个顶层函数。

    如果不想使用默认的类名,可以在 .kt 文件的开头加上 @file:JvmName("类名") 的注解。

    3.2 在 Java 中调用顶层属性

    和函数一样,属性也可以放到文件的顶层。默认情况下,顶层属性和其他任意的属性一样,是通过访问器暴露给 Java 使用的(如果是 val 就只有一个 getter,如果是 var 就对应 getter 和 setter )。如果想要把一个常量以 public static final 的属性暴露给 Java,可以使用 const 来修饰它。

    • KotlinMethod.kt
    //不可变。
    val kotlinVal = "kotlinValue"
    //可变。
    var kotlinVar = "kotlinVariable"
    //常量。
    const val kotlinConst = "kotlinConst"
    //顶层函数。
    fun kotlinFunc() {}
    
    • JavaCallKotlin.java
    public class JavaCallKotlin {
        public JavaCallKotlin() {
            KotlinMethodKt.kotlinFunc();
            //不可变。
            KotlinMethodKt.getKotlinVal();
            //可变。
            KotlinMethodKt.setKotlinVar("newKotlinVar");
            KotlinMethodKt.getKotlinVar();
            //常量。
            String kotlinConst = KotlinMethodKt.kotlinConst;
        }
    }
    

    4. 扩展函数

    扩展函数 其实是一个类的成员函数,只不过它定义在类的外面,我们所需要做的,就是在声明扩展函数的时候,把需要扩展的类或者接口的名称,放到它的前面,用来调用这个扩展函数的对象,就叫做 接收者对象。
    在扩展函数中,可以直接访问被扩展的类的其它方法和属性,就好像是在这个类自己的方法中访问它们的一样,但是扩展函数不允许你打破它的封装性,扩展函数不能访问私有的或者是受保护的成员。

    4.1 扩展函数的定义和使用

    给 String 类添加一个扩展函数,返回它的最后一个字符:

    fun main() {
        println("Kevin".lastChar())
    }
    
    fun String.lastChar() : Char = this.get(this.length - 1)
    

    4.2 扩展属性

    扩展属性提供了一种方法,用来扩展类的 API,可以用来访问属性,用的是属性语法而不是函数的语法,尽管他们被称为属性,但它们没有任何状态,因为没有合适的地方来存储它们。
    下面我们给 StringBuilder 添加一个可读写的属性 lastChar

    val String.lastChar:Char get() = get(length - 1)
    
    var StringBuilder.lastChar : Char
        get() = get(length - 1)
        set(value : Char) {
            this.setCharAt(length - 1,value)
        }
    
    fun main() {
        println("Kevin".lastChar)
    
        val sb = StringBuilder("Kevin?")
        sb.lastChar = '*'
        println(sb)
    }
    

    5. 字符串处理

    5.1 分割字符串

    在 Java 中,我们会使用 split 来分割字符串,它接受一个正则表达式作为参数。但是当我们想分割 "." 时,会得到一个空的数组,因为 . 号表示任何字符的正则表达式。
    而在 Kotlin 中,它提供了一个接受 Regex 类型的重载函数,这样确保了当有一个字符串传递给这些函数的时候,不会被当做正则表达式,我们可以使用扩展函数 toRegex 将字符串转换为正则表达式。

    fun main() {
        println("π = 3.14156-78.ABC".split("[.\\-]".toRegex()))
    }
    

    运行结果:

    [π = 3, 14156, 78, ABC]
    

    5.2 正则表达式

    获取 /Users/yole/kotlin-book/chapter.adoc 这个字符串的目录、文件名和扩展名。

    fun main() {
        parsePath("/Users/yole/kotlin-book/chapter.adoc")
    }
    
    
    fun parsePath(path : String) {
        val regex = """(.+)/(.+)\.(.+)""".toRegex()
        val matchResult = regex.matchEntire(path)
        if (matchResult != null) {
            val (dire,filename,extension) = matchResult.destructured
            println("Dir: $dire, name: $filename, ext: $extension")
        }
    }
    

    相关文章

      网友评论

          本文标题:Kevin Learn Kotlin:函数

          本文链接:https://www.haomeiwen.com/subject/tlkxxrtx.html