kotlin学习笔记之函数的定义与调用

2019-04-21  本文已影响0人  大荒里种菜

创建集合

// 创建一个set
val set1 = hashSetOf(1,7,53,"5",'A')
val set2 = hashSetOf<Int>(1,7,53)
    
 // 创建一个list
val list1 = arrayListOf<Int>(1,7,53)
    
// 创建一个map,to的含义接下来会讲述
val map = hashMapOf<Int,String>(1 to "one",7 to "seven", 53 to "fifty-three")

命名参数

// 定义函数
fun <T> joinToString(
        collection: Collection<T>,
        separator: String,
        prefix: String,
        postfixt: String
): String {
    val result = StringBuilder(prefix)

    for ((index, element) in collection.withIndex()) {
        if (index > 0) result.append(separator)
        result.append(element)
    }

    result.append(postfixt)
    return result.toString()
}

val list = arrayListOf(1, 7, 53)
// 调用时可以对参数进行命名
// 指明了一个参数的名称后,为了避免混淆,那之后的所有参数都需要表明名称
println(joinToString(collection = list, separator = ", ", prefix = "(", postfixt = ")"))

默认参数值

// 给参数赋予默认值后,在调用时可以省略
fun test(name: String = "张三", age: Int = 32) {
    print("name=$name,age=$age")
}

test("李四")
test(age = 25)
test()

顶层函数和顶层属性

函数和属性直接定义在kotlin文件的顶层中,可以简单理解为其声明位置紧跟importpackage关键字之后,其它文件需要使用可以使用import关键字导入,若出现名字冲突可以使用as关键字,如下所示:

import foo.Bar // Bar 可访问
import bar.Bar as bBar // bBar 代表“bar.Bar”

扩展函数

理论上来说,扩展函数非常简单,它就是一个类的成员函数,不过定义在类的外面。

class Test03{
    t(i: Int) {
        print(123)
    }
}

// 给类型是Test03定义扩展函数
fun Test03.lastChar() = t(1)    //调用Test03内部的t方法,也可以通过this.t(1)来调用

fun Test03.last() {
    // 没返回值
}

// 单行可以不用”{}“
fun Test03.first(): Int = 2

扩展属性

与扩展函数相似。

val String.lastChar: Char
     get() = get(length - 1)

var StringBuilder.lastChar: Char
    get() = get(length - 1)
    set(value: Char) {
        this.setCharAt(length - 1, value)
    }

可变参数

可变参数的关键字vararg,可以用来声明一个函数将可能有任意数量的参数。
展开运算符:*

// kotlin
fun listOf<T>(vararg values: T): List<T> {...}

// Java
public void fun(int... arg) {...}

fun main(args: Array<String>) {
    val list = listOf("args:", *args)
    println(list)
}

中缀调用和解构声明

一个中缀表示法,当调用一些只有一个参数的函数时,使用它会让代码更简练。
解构声明,用来把一个单独的组合值展开到多个变量中。

val map = mapOf(1 to "one", 7 to "seven", 53 to "fifty-three")

to不是内置的结构,而是一种特殊的函数调用,被称为中缀调用。中缀调用可以与只有一个参数的函数一起使用,无论是普通的函数还是扩展函数。要允许使用中缀符号调用函数,需要使用infix修饰符来标记它。

// 以下两种调用方式是等价的
1.to("one")
1 to "one"

// 声明,Any表示任意类型
infix fun Any.to(other: Any) = Pair(this, other)

// 一个简单的例子
class Test04 {
    infix fun to(str: String) {
        println("str=$str")
    }

    infix fun so(s: String) {
        println("str=$s")
    }
}

infix fun Test04.to(other: Int) = println(other)

fun main(args: Array<String>) {
    val t = Test04()
    t so "张三"
    t to "李四"
    t to 10
}
// str=张三
// str=李四
// 10

而解构声明适用于有返回值的中缀调用,比如kotlin标准库中的Pair,也就是上述中的举例代码。

// 例子
val (number, name) = 1 to "one"

// 为Test04添加一个内部类
infix fun r(i: Int): Int {
      return i;
}

// 在main方法中添加如下代码
val j = t r 10

字符串和正则表达式

// 用一个点号或者破折号来分割字符串
println("12.345-6.A".split("\\.|-".toRegex()))
// [12, 345, 6, A]

// 在给定分隔符第一次(或最后一次)出现之前(或之后)的字符串的函数
fun parsePath(path: String) {
    val directory = path.substringBeforeLast("/")
    val fullName = path.substringAfterLast("/")

    val fileName = fullName.substringBeforeLast(".")
    val extension = fullName.substringAfterLast(".")

    println("Dir:$directory,name:$fileName,ext:$extension")
}

fun main(args: Array<String>) {
    parsePath("/user/yole/kotlin-book/chapter.adoc")
}
// Dir:/user/yole/kotlin-book,name:chapter,ext:adoc

正则表达式写在一个三重引号的字符串中。在这样的字符串中,不需要对任何字符进行转义,包括反斜线,所以可以用\.而不是\\.来表示点。

fun parsePath(path: String) {
    val regex = """(.+)/(.+)\.(.+)""".toRegex()
    val matchResult = regex.matchEntire(path)
    if(matchResult !=null) {
        val (directory,fileName,extension) = matchResult.destructured
        println("Dir:$directory,name:$fileName,ext:$extension")
    }
}

fun main(args: Array<String>) {
    parsePath("/user/yole/kotlin-book/chapter.adoc")
}
// Dir:/user/yole/kotlin-book,name:chapter,ext:adoc

val kotlinLogo = """
        .|  //
        .| //
        .| /
    """.trimMargin(".")  // 删除每行中的前缀和前面的空格
    println(kotlinLogo)
上一篇下一篇

猜你喜欢

热点阅读