Kotlin,哪个更好,使用"is"或"as?",



两个函数test1和test2,一个用"is"检查类型,一个使用"as?

使用"Is"one_answers"as?"有比较吗?对这两个词的一般用法有什么建议?

class Message(val int: Int, val msg:String)
class Test {
fun test1(objList: List<Any?>) {
for (i in objList.size - 1 downTo 0) {
val item = objList.get(i)
if (item is Message) {
println(item)
}
}
}
fun test2(objList: List<Any?>) {
for (i in objList.size - 1 downTo 0) {
(objList.get(i) as? Message)?.let {item ->
println(item)
}
}
}
}

因此,如果您查看两者的JVM字节码:

// JVM bytecode of test1
L5
LINENUMBER 8 L5
ALOAD 3
INSTANCEOF com/example/artifact/Message
IFEQ L6
// JVM bytecode of test2
L4
LINENUMBER 16 L4
ALOAD 0
ILOAD 1
INVOKEINTERFACE java/util/List.get (I)Ljava/lang/Object; (itf)
DUP
INSTANCEOF com/example/artifact/Message
IFNE L5
POP
ACONST_NULL
L5
CHECKCAST com/example/artifact/Message
DUP
IFNULL L6
ASTORE 3

您可以清楚地看到,test1只检查类型,它智能地强制转换结果,而test2首先检查实例是否属于该类型,然后返回null或显式地将其"强制转换"为该类型。

因此,通过观察,我建议您使用is运算符,因为它对这些任务进行了更优化。如果你不喜欢使用大括号,那么你可以像python一样省略它们,或者把println放在与If条件相同的行上。

如果你想的话,这是一个更优化的代码:

fun test1(objList: List<Any>) {
for (item in objList.asReversed()) {
if (item is Message) println(item)
}
}
fun test2(objList: List<Any>) {
for (item in objList.asReversed()) {
(item as? Message)?.let { println(it) }
}
}

as?版本可能少了一行代码,但它真的整体代码少了吗?你可能已经摆脱了:

val item = objList.get(i)

但你用代替了它

(objList.get(i) as? Message)?.let {item ->

在这种情况下,我认为as?版本比is版本需要更多的时间来理解,后者更简单。我还怀疑这两种方法在性能上是否存在显著差异。一般来说,除非您已经分析了应用程序中的实际性能问题,否则总是更喜欢可读性更强的代码而不是性能更高的代码。是否存在性能问题在很大程度上取决于应用程序的上下文。记住,过早的优化是万恶之源。

如果你真的想要更少的代码,那么考虑使用以下代码:

fun test(objList: List<Any>) = objList.asReversed().forEach {
if (it is Message) println(it)
}

这利用了:

  • 单表达式函数
  • List.asReversed(返回原始列表的反向视图(
  • Iterable.forEach
  • it:单个参数的隐式名称(在lambda表达式中(

is是类型检查。as型铸造。

不同的是

is返回布尔值、真或假

as返回该类型

如果您只想得到"是"或"否",请使用is

示例

if (user is Login)你只是想要答案是还是不是?然后你做其他事情

当您想尝试转换为该类型的时,可以使用as

示例

(user as? Admin).let{print(it.name.toString())} 

您要检查的这个用户是否为is Admin or not如果是,您想使用该用户值来打印类似名称的内容

所以对于条件使用is

铸造用as

fun test(objList: List<Any>) = objList.asReversed().forEach {
when(it){ is Message -> println(it)}
}

相关内容

最新更新