前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Android面试题之Kotlin 扩展函数和apply函数详解

Android面试题之Kotlin 扩展函数和apply函数详解

作者头像
AntDream
发布2024-06-13 21:01:18
1080
发布2024-06-13 21:01:18
举报
扩展函数
  • 扩展可以在不直接修改类定义的情况下增加类功能
  • 扩展可以用于自定义类,也可以用于标准函数
  • 和继承相似,扩展也能共享类行为,在无法接触某个类定义,或者某个类没有使用open修饰符,导致无法继承它时,扩展就是增加类功能的最好选择
  • 和定义一般函数差不多,但需要指定接收功能扩展的接受者类型
  • 默认是public,整个工程有效,若需要只在当前文件有效,可以定义为private
  • 扩展函数里自带了接收者对象的this隐式调用
代码语言:javascript
复制
//给字符串追加若干个感叹号
fun String.addExt(amount:Int = 1) = this + "!".repeat(amount)
//在超类上定义扩展函数,Any的所有子类都能使用该函数
fun Any.easyPrint() = println(this)

class TeBot()

fun main() {
    println("abc".addExt(2))
    "abc".easyPrint()
    val teBot = TeBot()
    teBot.easyPrint()
}
泛型扩展函数

新的泛型扩展函数不仅可以支持任何类型的接受者,还保留了接收者的类型信息

代码语言:javascript
复制
//泛型扩展函数
fun <T> T.easyPrint2():T{
    println(this)
    return this
}

fun main() {
    println("abc".addExt(2))
    "abc".easyPrint2().addExt(2).easyPrint2()
}
可空类扩展
  • 在可空类上定义扩展函数,可以直接在扩展函数体内解决可能出现的空值问题
  • infix关键字适用于有单个参数的扩展和类函数。如果一个函数定义使用了infix关键字,那么调用它时,接收者和函数之间的点操作以及参数的一对括号都可以不要
代码语言:javascript
复制
//可空类型扩展函数
//fun String?.printWIthDefault(default:String) = print(this ?: default)
infix fun String?.printWIthDefault(default:String) = print(this ?: default)

fun main() {
    val nullableString: String? = "efg"
//    nullableString.printWIthDefault("abc")
    //加了infix关键字
    nullableString printWIthDefault "abc"
}
扩展属性
代码语言:javascript
复制
//增加统计元音字母属性
val String.numVowels
    get() = count{
        "aeiou".contains(it)
    }

fun main() {
    "the people's republic of china".numVowels.easyPrint()
}
扩展文件和重命名扩展
代码语言:javascript
复制
package extention
//扩展文件
fun <T> Iterable<T>.randomTake(): T = this.shuffled().first()



import extention.randomTake
//重命名扩展
import extention.randomTake as random

//扩展文件

fun main() {
    val list = listOf("Jak", "Jim")
    val set = setOf("Jak", "Jim")
    list.randomTake()
    list.random()
}
apply函数详解
代码语言:javascript
复制
import java.io.File

//apply函数中的扩展函数
//从T.apply可以看出apply本身是一个扩展函数,并且是泛型扩展函数 返回类型是泛型T
//入参block是一个匿名函数() -> Unit,
// T.() -> Unit表示的是一个扩展函数,在T上扩展了一个匿名函数,
// 之所以要传扩展函数是因为扩展函数内部包括隐式调用,有this
//匿名函数也可以是扩展函数,下面的匿名函数的内部this指向一个File对象
//File.() -> Unit

public inline fun <T> T.apply(block: T.() -> Unit): T {
    block()
    return this
}

fun main() {
    File("xxx").apply {
        setWritable(true)
        setReadable(true)
    }
    //分解一下
    //1.定义扩展函数
    fun File.ext() : Unit {
        setReadable(true)
    }
    //2.给block赋值
    val block = File::ext
    //3.传入apply函数
    File("xxx").apply(block)
}

码字不易,求转发,求点在看,求关注,感谢!

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-05-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 AntDream 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 扩展函数
  • 泛型扩展函数
  • 可空类扩展
  • 扩展属性
  • 扩展文件和重命名扩展
  • apply函数详解
  • 码字不易,求转发,求点在看,求关注,感谢!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档