Kevin Learn Kotlin:函数

2021-12-02  本文已影响0人  Kevin_小飞象
每日一图.jpg

Kotlin 的函数

1. 方法声明

16.png
/**
 * 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.")
    }
}
fun main() {
    println(NumUtils.double(3))   // 6
}

object NumUtils {
    fun double(num : Int) : Int {
        return num * 2
    }
}
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

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 根据包含函数的文件的名称生成的类:

fun kotlinFunc() {}
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 来修饰它。

//不可变。
val kotlinVal = "kotlinValue"
//可变。
var kotlinVar = "kotlinVariable"
//常量。
const val kotlinConst = "kotlinConst"
//顶层函数。
fun kotlinFunc() {}
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")
    }
}
上一篇下一篇

猜你喜欢

热点阅读