Cuando los parameters lambda deben ser noinline en Kotlin?

A menudo encuentro errores en las funciones inline de Kotlin donde los parameters lambda deben marcarse sin línea. Otras veces, los parameters lambda parecen funcionar bien. He leído la documentation de Kotlin de las funciones en línea , y parece que este es el pasaje operativo que explica la regla:

Las lambdas insertables solo se pueden llamar dentro de las funciones en línea o se pueden pasar como arguments ineludibles, pero las que no están en línea se pueden manipular de la manera que se desee: almacenadas en campos, aprobadas, etc.

Tengo problemas para desempacar esos conceptos. Específicamente, no estoy seguro de entender por completo las cosas que no puedo hacer (incluido todo lo que está en "etc.") con una lambda en línea, en otras palabras, las cosas que lo descalificarían para que no esté en línea. ¿Hay una buena reference o más explicación / ejemplos de usos que descalifiquen a un parámetro lambda de Kotlin de estar en línea?

Es less "descalificante" que la lambda no esté en línea y más de "esta acción no se puede realizar en una lambda en línea".

Yo como que respondí esto aquí .

Los methods integrados se insertan directamente en el sitio de llamada, al igual que cualquier lambda en línea.

Para reutilizar mi viejo ejemplo,

esto resulta más o less main aquí:

 fun withLambda(lambda: () -> Unit) { lambda() } inline fun inlinedLambda(lambda: () -> Unit) { lambda() } fun main(args: Array<String>) { withLambda { println("Hello, world") } inlinedLambda { println("Hello, world") } } 

siendo convertido a esto:

 fun main(args: Array<String>) { withLambda { println("Hello, world") } println("Hello, world") // <- Directly inserted! } 

Lo que no puedes hacer con un lambda en línea es tratarlo como un object .

Esto significa que no puede almacenarlo en un campo:

 val a = lambda // <-- error 

o llamar a methods en él:

 lambda.toString() // <-- error 

porque no es un object

Tampoco se puede pasar como argumento a otra function

 func(lambda) // <-- error 

a less que el lambda esté marcado como crossinline , y el parámetro de la otra function esté en inline .

Esto es básicamente establecido por la documentation.

Los que no están en línea se pueden manipular de la manera que nos guste: almacenados en campos, pasados ​​de un lado a otro, etc.

Tenga en count que algunas funciones en línea pueden llamar a las lambdas pasadas a ellas como parameters … Para indicar eso, el parámetro lambda debe marcarse con el modificador crossinline:

Piense en lambdas inline como tener su código insertado directamente en el método. Conceptualmente, en realidad no existen, y "llamarlos" simplemente insertá sus contenidos en el método de llamada.

  • ¿Cómo mejorar la syntax de kotlin lambda?
  • Tipo de function con receptor en Scala
  • Comparador como lambda
  • ¿Por qué no puedo usar lambda para la interfaz en kotlin?
  • Expresiones de kotlin lambda como parámetro opcional
  • Kotlin lambdas sin usar objects
  • kotlin cómo referir el scope externo esto en funciones de aplicación multicapa
  • Tipo de function de Kotlin en su lugar interfaz funcional lambda
  • Emitir no seleccionado al lanzar un object de tipo Cualquiera? en una lambda en kotlin
  • Kotlin Cualquiera con lambdas
  • Pasando lambda en lugar de interfaz