- Kotlin 的函数
- 1. 方法声明
- 2. 方法参数
- 3. 顶层函数和属性
- 3.1 在 Java 中调用顶层函数
- 3.2 在 Java 中调用顶层属性
- 4. 扩展函数
- 4.1 扩展函数的定义和使用
- 4.2 扩展属性
- 5. 字符串处理
- 5.1 分割字符串
- 5.2 正则表达式
- 普通类的方法 实现一个普通类,可以借助关键字 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")
}
}