假设我们有像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 String
为text
,这些方法会引发异常。
答案 0 :(得分:11)
它们几乎相同,但第一个会抛出KotlinNullPointerExcption
null
,第二个抛出TypeCastException
。
答案 1 :(得分:3)
不同之处在于KotlinNullPointerExcption
(正如@ Miha_x64所述)在每个其他方面产生相同字节码时得到的异常(TypeCastException
或text == 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时才会抛出错误。