前言
写代码的时候往往会用到类型检测is
和类型转换as
或者空安全的类型转换as?
,在这里记录一下使用as?
的一点优化。
正常使用
举个例子1
2
3
4
5
6
7
8
9
10
11
12
fun getCurrentProcessName(context: Context?): String {
return try {
(context?.getSystemService(Context.ACTIVITY_SERVICE) as? ActivityManager)
?.runningAppProcesses
?.first { it.pid == android.os.Process.myPid() }
?.processName
?: ""
} catch (e: Exception) {
""
}
}
在正常使用的时候,往往是要在外面加一层括号()
,这样写代码就很麻烦,不能一步到位,那要怎么样才能把这括号删掉呢?
加工之后
首先我们要想到扩展和reified
,然后写一个方法来实现类型转换:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
inline fun <reified T> Any?.asType(): T? {
// 如果类型转换成功,那么返回对应的`T`类型,如果转换失败,那么就会返回`null`
return this as? T
}
// 或者
// 这个方法是https://droidyue.com/blog/2020/03/29/kotlintips-as-type/,里面的实现
inline fun <reified T> Any.asType1(): T? {
// 先检查this的类型,如果是T则返回T,否则返回null
return if (this is T) {
this
} else {
null
}
}
说一下is
、as
、as?
的区别
is
是表示类型检查,与Java的instanceof
一样as
是表示不安全的类型转换,但是左边的类型如果是空的那么就会抛出一个异常,这就是所谓的不安全的,对应Java的强转as?
则表示安全的类型转换,如果转换失败则不会抛出异常,而是直接返回null
,对应Java的话则是if (test instanceof String) String str = (String) test
,先instanceof
,然后再强转。
所以上面两种写法都可以用,最终实现的目的都是一样的,最后看调用的代码:1
2
3
4
5
6
7
8
9
10
11
12
13
fun getCurrentProcessName(context: Context?): String {
return try {
context?.getSystemService(Context.ACTIVITY_SERVICE)
?.asType<ActivityManager>()
?.runningAppProcesses
?.first { it.pid == android.os.Process.myPid() }
?.processName
?: ""
} catch (e: Exception) {
""
}
}
这样写起来的会就很顺畅了,直接一步到位,不用再写完as
之后在写一个括号,然后再回来接着写下面的代码。