转载

针对as?的使用优化

写代码的时候往往会用到类型检测 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
    }
}

说一下 isasas? 的区别

  • 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 之后在写一个括号,然后再回来接着写下面的代码。

原文  https://www.jowanxu.top/2020/04/13/Kotlin_asType/
正文到此结束
Loading...