在 Java 中,有个叫 SuppressWarnings 的注解,用于忽略特定的编译器警告。Kotlin 中也有一个类似功能的注解,叫做 Suppress,本文主要讲讲这个注解有什么用。
常规用法
有时候会写出这样的一些代码,这些在Kotlin编译器的眼里可能出现问题的代码,实际上却非常正确,跑起来不会出任何问题。
然后你就得到了一个编译器警告(warning),甚至是编译错误(error)。
比较常见的,比如说 unchecked cast:
-
val some: List<*> = emptyList<Nothing>()
-
some as List<String> // Unchecked cast: List<*> to List<String>
然后就可以使用 Suppress 取消这个 warning:
-
val some: List<*> = emptyList<Nothing>()
-
@Suppress("UNCHECKED_CAST")
-
some as List<String>
再举个例子:
-
sealed class Base {
-
@Suppress("LeakingThis")
-
val code = calculate()
-
abstract fun calculate(): Int
-
class Derived : Base() {
-
override fun calculate() = 42
-
}
-
}
上面这代码并不会出现 warning 的具体说明里的问题,所以使用了 Suppress 解决这个 warning。
这是很简单的破事水,没有任何讨论的价值。
然后下面是正文。
好孩子不要模仿!很危险的!
非常规用法
这破注释竟然能消除 error!
比如说这样的代码:
-
println((null as String?).length)
编译器会告诉你这样是不对的,然后向你丢出了一个 error:
-
Only safe (?.) or non-null asserted (!!.) calls are allowed on a nullable receiver of type String?
然后就可以使用 Suppress 让编译器闭嘴!
-
@Suppress("UNSAFE_CALL")
-
println((null as String?).length)
然后就可以顺利的通过编译,编译后跑一跑,就可以轻松地拿到一个空指针异常:
-
Exception in thread "main" java.lang.NullPointerException
-
at .......
很简单,有了 Suppress,你就可以让这些可以本来通过编译器生成java字节码,但是因为各种各样的原因(例如类型安全)被ban掉的代码,顺利通过编译。
下面给几个可能有用的例子。
例1
-
fun some(any: Any) {
-
when(any) {
-
is Array<String> -> println(any.size)
-
}
-
}
这是我吐槽过的「Java能做但是Kotlin做不了的事」系列之一。不考虑Kotlin的其他target(如js),在Jvm平台上有如下的迂回:
-
any is Array<*> && any.isArrayOf<String>()
就是很丑罢了。
在Kotlin的早期代码,这样的type check是允许的,因为某些原因ban掉了(读者可以想想为什么要ban掉这样的代码)。这个时候可以用 Suppress 把这个后门打开。
-
@Suppress("CANNOT_CHECK_FOR_ERASED")
例2
类型别名。
-
class Some {
-
@Suppress("TOPLEVEL_TYPEALIASES_ONLY")
-
typealias Str = String
-
val a: Str = ""
-
}
一目了然,不解释。
例3
Kotlin 在远古版本 M13 新增了 lateinit 修饰符,可以对只读属性和可变属性使用。
然后 M14 版本就残忍地 ban 掉了 lateinit val。
-
@Suppress("INAPPLICABLE_LATEINIT_MODIFIER")
-
lateinit val lateInitVal: String
lateinit val 的用处可以看上面 M13 的链接里面的说明。
例4
Kotlin Collection Literals 半成品。
-
@Suppress("UNSUPPORTED")
-
val bs: BooleanArray = [true, false, true]
这是个未完成的功能,目前只支持数组。以后可以支持 List、Map 和 Set,所以为了避免不必要的兼容性麻烦,在正常情况下只允许在注解里这样用。要想在其他地方用,就像上面代码那样。
结尾
想知道更多的Suppress选项的话,可以去翻Kotlin的源码。
这种无法得到官方支持的奇技淫巧,也许下次更新就挂掉了,所以如果用了那就后果自负吧。
转载请注明出处:微信公众号 Kotlin
今天的文章Kotlin Suppress 的非常规用法分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/63209.html