什么时候可以使用“ as”运算符?

时间:2018-10-08 19:46:52

标签: casting kotlin

我有以下程序:

fun main(args: Array<String>) {
    var a: Int
    var b = 23.5
    a = b as Int
    println(a)
}

如果我运行它,程序将抛出java.lang.ClassCastException异常。

由于Kotlin中使用的数据类型表示为对象,因此我可以理解为什么无法像我一样轻率地转换它们,而应该使用与每种类型关联的内置转换方法或“安全”方法as?运算符-但这带来了一个问题:您何时(或应该)使用as运算符?

2 个答案:

答案 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)
}

但是,asas?仍然是相关的,例如:

fun test(foo: Any) {
  val fooString = foo as? String ?: throw IllegalArgumentException()
  ...
}

总体而言,请尽可能多地使用智能投射,并在特定情况下保留asas?

答案 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编译器非常聪明,大多数时候它已经知道值可以是什么类型,因此不需要经常进行强制转换。在某些情况下,您仍然知道编译器不了解的内容,并且适合使用强制类型转换。但其中太多的内容可能是“代码异味”,表明可能有更好的方法。

相关问题