写代码的时候往往会用到类型检测 is
和类型转换 as
或者空安全的类型转换 as?
,在这里记录一下使用 as?
的一点优化。
举个例子
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
,然后写一个方法来实现类型转换:
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
,然后再强转。 所以上面两种写法都可以用,最终实现的目的都是一样的,最后看调用的代码:
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
之后在写一个括号,然后再回来接着写下面的代码。