我有以下程序:
fun main(args: Array<String>) {
var a: Int
var b = 23.5
a = b as Int
println(a)
}
如果我运行它,程序将抛出java.lang.ClassCastException
异常。
由于Kotlin中使用的数据类型表示为对象,因此我可以理解为什么无法像我一样轻率地转换它们,而应该使用与每种类型关联的内置转换方法或“安全”方法as?
运算符-但这带来了一个问题:您何时(或应该)使用as
运算符?
答案 0 :(得分:1)
Kotlin编译器的智能强制转换非常聪明,因此在大多数情况下,您不需要显式强制转换。 Java代码:
Object foo = "foo";
if (foo instanceof String) {
String fooString = (String) foo;
System.out.println(fooString.length);
}
将翻译成以下Kotlin代码:
val foo: Any = "foo"
if (foo is String) {
println(foo.length)
}
但是,as
和as?
仍然是相关的,例如:
fun test(foo: Any) {
val fooString = foo as? String ?: throw IllegalArgumentException()
...
}
总体而言,请尽可能多地使用智能投射,并在特定情况下保留as
和as?
。
答案 1 :(得分:1)
在您的示例中,b
是一个Double
浮点值,而不是Int
。 (如其他答案所指出。)要转换它,您需要使用类似b.toInt()
的东西。
您的程序不会将其转换,因为 Kotlin的as
运算符不会将值更改为新的类型;而是告诉编译器该值已经是所需类型的 。。这称为 cast 。
例如,如果我有:
val n: Number = 4
然后,n
的类型为Number
。它的当前值实际上是Int
(它是Number
的子类)。因此,在这种情况下,我可以将其转换为Int
,例如:
val i = n as Int
之后,编译器将像Int
一样对其进行处理。
(这种特殊情况是 down-cast ,因为Int
在类层次结构中位于Number
之下。通常,向上广播是安全的,但是向下广播如果不是使用浮点数初始化n
,则其值将为Double
类型,它是Number
的另一个子类,而不是Int
;如您所见,程序会在运行时失败并抛出ClassCastException
。这就是为什么Kotlin也有一个安全铸造运算符as?
,该运算符提供null而不是例外。)
Kotlin编译器非常聪明,大多数时候它已经知道值可以是什么类型,因此不需要经常进行强制转换。在某些情况下,您仍然知道编译器不了解的内容,并且适合使用强制类型转换。但其中太多的内容可能是“代码异味”,表明可能有更好的方法。