Kotlin 科特林“;无需浇铸“;在IDE中

Kotlin 科特林“;无需浇铸“;在IDE中,kotlin,intellij-idea,Kotlin,Intellij Idea,我是Kotlin(和Java)的新手,所以这可能是个愚蠢的问题,但IntelliJ在第二次函数调用时一直告诉我“不需要强制转换”。如果我切换功能的顺序,则其他功能的顺序相同 我可以想象两件事: 科特林很聪明,他知道:嘿,第一个演员很好,所以我会选第二个 智能问题 (this as Exec).setVersionToDeploy() (this as Exec).setEcsTaskMemory() 这两个函数都定义为(Gradle插件): 你的第一个猜测是正确的 这被称为:编译器知道

我是Kotlin(和Java)的新手,所以这可能是个愚蠢的问题,但IntelliJ在第二次函数调用时一直告诉我“不需要强制转换”。如果我切换功能的顺序,则其他功能的顺序相同

我可以想象两件事:

  • 科特林很聪明,他知道:嘿,第一个演员很好,所以我会选第二个

  • 智能问题

    (this as Exec).setVersionToDeploy()
    (this as Exec).setEcsTaskMemory()
    
这两个函数都定义为(Gradle插件):


你的第一个猜测是正确的

这被称为:编译器知道,如果执行到达第二行,
This
的类型必须是
Exec
(否则第一行会抛出一个
ClassCastException
,它不会到达第二行)。因此它推断出特定的类型,不需要进一步的强制转换

一般来说,编译器会在这样的情况下推断类型,因此不需要显式强制转换(这样做不是错误,只是警告;但IDEA非常热衷于展示改进代码的方法)

这种情况最常见于可空性(因为这是类型系统的一部分)。例如,如果您有一个可空字段,编译器将不允许您直接调用其方法:

val myString: String? = "abc"
println(myString.length) // COMPILE ERROR, as myString could be null
但如果添加手动检查,编译器会将字段强制转换为不可为null的类型,因此不需要强制转换:

val myString: String? = "abc"
if (myString != null)
    println(myString.length) // OK; compiler infers type String

第一个,如果第一次强制转换失败,那么它将抛出,这样第二行就不会执行。
val myString: String? = "abc"
if (myString != null)
    println(myString.length) // OK; compiler infers type String