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文件的顶层中,可以简单理解为其声明位置紧跟import
或package
关键字之后,其它文件需要使用可以使用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
- 可以使用
this
关键字 - 可以直接访问被扩展的类的成员函数和方法,除了私有的或受保护的
- 可以使用
import
关键字来导入(注意名字冲突时使用as
) - 可以对库类、集合添加扩展函数,如
String
- 不能重写扩展函数
扩展属性
与扩展函数相似。
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)