开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第23天,点击查看活动详情
一、扩展函数
扩展函数允许我们去扩展一个类的函数,这种特性是 Java 中所没有的
1)、扩展函数的语法结构如下:
fun ClassName.methodName(params1: Int, params2: Int) : Int{
}
相比于普通的函数,扩展函数只需要在函数前面加上一个 ClassName. 的语法结构,就表示把该函数添加到指定的类中
2)、一般我们要定义哪个类的扩展函数,我们就定义一个同名的 Kotlin 文件,便于后续查找,虽然说也可以定义在任何一个类中,但是更推荐将它定义成顶层方法,这样可以让扩展方法拥有全局的访问域
3)、扩展函数默认拥有这个类的上下文环境
例如我们现在要给 String 这个类扩展一个 printString 方法,我们就可以新建一个 String.kt 的文件,然后在这个文件下面编写扩展函数:
fun String.printString(){
println(this)
}
fun main() {
val name = "erdai"
name.printString()
}
//打印结果
erdai
4)、指向扩展函数的引用
1、语法结构:String::method1 前缀类::函数名
fun String.method1(i: Int) {
print(this + i)
}
//我们这么写就可以拿到一个函数的引用
String::method1
2、扩展函数引用的调用,只能在顶层扩展函数中使用
fun String.method1(i: Int) {
print(this + i)
}
//可转换成如下函数
fun method1(s: String,i: Int){
println(s + i)
}
//下面调用方式是等价的
fun main() {
(String::method1).invoke("erdai",666)
(String::method1)("erdai",666)
"erdai".method1(666)
}
//打印结果
erdai666
3、扩展函数类型
fun String.method1(i: Int) {
print(this + i)
}
//有 Receiver
val a: String.(Int) -> Unit = String::method1
//无 Receiver
val b: (String,Int) -> Unit = String::method1
4、对有无 Receiver 类型相互转换,让他们进行一个反向的调用
fun method3(s: String,i: Int){
}
fun String.method4(i: Int){
}
fun main() {
//method3
val f: String.(Int) -> Unit = ::method3
"erdai".f(666)
//method4
val g: (String,Int) -> Unit = String::method4
"erdai".method4(666)
}
二、扩展属性
1)、类似下面这种语法结构
var ClassName.attr: Char
get() = ...
set(value) = ...
相比于普通的属性,扩展属性只需要在属性前面加上一个 ClassName. 的语法结构,就表示把该扩展属性添加到指定的类中
2)、一般我们要定义哪个类的扩展属性,我们就定义一个同名的 Kotlin 文件,便于后续查找,虽然说也可以定义在任何一个类中,但是更推荐将它定义成顶层属性,这样可以让扩展属性拥有全局的访问域
3)、扩展属性默认拥有这个类的上下文环境
val String.lastUpperCaseChar: Char
get() = get(length - 1).toUpperCase()
var StringBuilder.lastChar : Char
get() = get(length - 1)
set(value) {setCharAt(length - 1,value)}
fun main() {
//扩展属性测试
val name = "erdai"
println(name.lastUpperCaseChar)
val str = StringBuilder("erdai")
str.lastChar = 'g'
println(str.toString())
}
//打印结果
I
erdag
三、总结
本篇文章我们介绍了 Kotlin 中的扩展函数和扩展属性,这是 Java 所没有的,掌握它们可以在一定程度上提高我们的开发效率
好了,本篇文章到这里就结束了,希望能给你带来帮助 🤝