是"双重感叹"与"相同"在科特林?

时间:2018-02-13 21:16:16

标签: kotlin

假设我们有像SELECT sum(CASE WHEN ded.ACTION = 'A' --added deduction THEN CASE WHEN REGEXP_LIKE(ded.oper_ID, '[[:digit:]]') THEN 1 ELSE 0 END) END AS "Added By Clients", -- count # of client deductions sum(CASE WHEN ded.ACTION = 'A' -- added deduction THEN CASE WHEN NOT REGEXP_LIKE(ded.oper_ID, '[[:digit:]]') THEN 1 ELSE 0 END) END AS "Added by Internal Reps" -- count # of internal rep deductions sum(CASE WHEN ded.ACTION <> 'A' --modified deduction THEN CASE WHEN REGEXP_LIKE(ded.oper_ID, '[[:digit:]]') THEN 1 ELSE 0 END) END AS "Modified By Clients", -- count # of client deductions sum(CASE WHEN ded.ACTION <> 'A' -- modified deduction THEN CASE WHEN NOT REGEXP_LIKE(ded.oper_ID, '[[:digit:]]') THEN 1 ELSE 0 END) END AS "Modified by Internal Reps" -- count # of internal rep deductions FROM DEDUCTIONS_TBL DED 这样的变量。

当我想将它转换为非可空类型时,我可以使用:

  • var text: String?
  • text!!

他们的意思是一样吗?

我知道如果text as Stringtext,这些方法会引发异常。

4 个答案:

答案 0 :(得分:11)

它们几乎相同,但第一个会抛出KotlinNullPointerExcption null,第二个抛出TypeCastException

答案 1 :(得分:3)

不同之处在于KotlinNullPointerExcption(正如@ Miha_x64所述)在每个其他方面产生相同字节码时得到的异常(TypeCastExceptiontext == null)。演员和!!仅在当前语句中有效,因此行为不太可能发生变化。我每次都会去!!,因为异常更好地反映了错误。

fun foo() {
    var s = ""
    val t: String? = ""

    if (t as String != "") s = "1"
    if (t!! != "") s = "2"
}

产量

public final foo()V
L0
  LINENUMBER 9 L0
  LDC ""
  ASTORE 1
L1
  LINENUMBER 10 L1
  LDC ""
  ASTORE 2
L2
  LINENUMBER 12 L2
  ALOAD 2
L3
  LDC ""
  INVOKESTATIC kotlin/jvm/internal/Intrinsics.areEqual (Ljava/lang/Object;Ljava/lang/Object;)Z
  ICONST_1
  IXOR
  IFEQ L4
  LDC "1"
  ASTORE 1
L4
  LINENUMBER 13 L4
  ALOAD 2
L5
LDC ""
  INVOKESTATIC kotlin/jvm/internal/Intrinsics.areEqual (Ljava/lang/Object;Ljava/lang/Object;)Z
  ICONST_1
  IXOR
  IFEQ L6
  LDC "2"
  ASTORE 1
L6
  LINENUMBER 14 L6
  RETURN
L7
  LOCALVARIABLE t Ljava/lang/String; L2 L7 2
  LOCALVARIABLE s Ljava/lang/String; L1 L7 1
  LOCALVARIABLE this Lde/leo; L0 L7 0
  MAXSTACK = 2
  MAXLOCALS = 3

有趣的部分是 L3 L5

答案 2 :(得分:2)

在产生的异常中有所不同:

如果TypeCastException

,则可归零值转换为非空类型会导致null
val s: String? = null
val s2 = s as String //kotlin.TypeCastException: null cannot be cast to non-null type kotlin.String

双重感叹号,双重爆炸,意味着您不关心类型的可空性信息,只是想要使用它,就像它不能null一样。如果是,则抛出NullpointerException

val s: String? = null
val s2: String = s!! //Exception in thread "main" kotlin.KotlinNullPointerException

您应该很少使用这两个选项中的任何一个并谨慎处理可空性:

s?.let {
    //it's safe here!
} ?: //optionally handle null case

Smart casting也会帮助你。

答案 3 :(得分:1)

它们是相同的,如果使用不正确,它们将抛出异常错误。根据{{​​3}}使用as运算符时,您执行的是不安全的操作,如果它们的类型不同,则会抛出错误,而docs {{1}只有当unwraped变量为null时才会抛出错误。