¿Por qué todavía es necesario lanzar el tipo aunque ya se haya asegurado en este ejemplo?

Hoy encontré esta sección en Kotlin Docs . Llamados "moldes inteligentes", Kotlin parece "insert yesos (seguros) automáticamente cuando sea necesario":

En muchos casos, no es necesario utilizar operadores de conversión explícitos en Kotlin, porque el comstackdor realiza un seguimiento de is-checks para valores inmutables e inserta moldes (seguros) automáticamente cuando es necesario:

fun demo(x: Any) { if (x is String) { print(x.length) // x is automatically cast to String } } 

No entiendo qué hace el "casting inteligente" en este ejemplo. Parece que no hay nada que requiera un casting, ya que x siempre será String y, por lo tanto, x.length siempre funcionará, no se requiere conversión. ¿Qué está sucediendo exactamente en la línea de print ? ¡Gracias por adelantado!

x tiene un tipo Any , y ese tipo no tiene una propiedad .length . Sin embargo, dado que dentro del bloque if , se sabe que x es en realidad un String , obtiene ese tipo de conversión inteligente, y puede llamar a methods y acceder a las properties de la class String en él.

La versión de Java de este código se vería así, necesitaría un lanzamiento explícito a String incluso después de hacer la verificación de tipo:

 void demo(Object x) { if(x instanceof String) { System.out.print(((String) x).length()); } } 

Esto es lo que simplifica Kotlin para ti.

Sin un casting inteligente, tendría que decirle al comstackdor que el tipo es en realidad un String, ya que la length no existe en Any.

 println((x as String).length) 

Con el casting inteligente esto ya no es necesario.