romper o continuar saltar a través del límite de class kotlin

¿Alguien está enfrentando este problema? break or continue jump across class boundary kotlin

este problema aparece cuando voy a usar break o continue. dentro de lambda con receptor creo 'letIn'

lambda con código de receptor

 fun letIn(componentName: String?, values: List<LifeService.Value?>?, body: (String, List<LifeService.Value?>) -> Unit) { if (!TextUtils.isEmpty(componentName) && (values != null && values.isNotEmpty())) { body(componentName!!, values) } } 

este código de muestra para eso.

 for (option in 0 until optionsSize) { val component = optionsGroup?.options?.get(option) component?.let { with(component) { letIn(presentation, values, { componentName, values -> if (componentName == LifeComponentViewType.CHECKBOX) { letIn(transformCheckBoxValues(optionsGroup), { data -> dataSource?.push(componentName, ComponentDataCheckBoxCollection(name, data)) view.buildComponent(componentName) // break or continue didnt work }) } else { dataSource?.push(componentName, ComponentDataCollection(name, values)) view.buildComponent(componentName) } }) } } } 

porque el código anterior no funcionó, así que lo uso de manera imperativa.

 for (option in 0 until optionsSize) { val component = optionsGroup?.options?.get(option) if (component != null) { val presentation: String? = component.presentation val values = component.values if (!TextUtils.isEmpty(presentation)) { if (presentation == LifeComponentViewType.CHECKBOX) { val data = transformCheckBoxValues(optionsGroup) if (data.isNotEmpty()) { dataSource?.push(presentation, ComponentDataCheckBoxCollection(optionsGroup.name, data)) view.buildComponent(presentation) return } } else { dataSource?.push(presentation!!, ComponentDataCollection(component.name, values)) view.buildComponent(presentation!!) } } else { return } } } 

¿alguien tiene sugerencias?

(Otros errores de encoding a un lado) Estás viendo el error porque dentro de tu lambda, no puedes usar break o continue saltando de la lambda al loop más cercano. En cambio, puede usar un return calificado para saltar de la lambda a una label.

Refiriéndose a la reference de idioma

La expresión de retorno regresa de la function envolvente más cercana, es decir, foo. (Tenga en count que dichos retornos no locales solo se admiten para expresiones lambda pasadas a funciones en línea.) Si necesitamos regresar de una expresión lambda, debemos labelrla y calificar la statement :

(Énfasis mío)

Su segundo ejemplo muestra que desea que sus lambdas realicen un retorno no local desde la function adjunta. Por lo tanto, no necesita calificar su return , pero su function letIn debe declararse en inline (de lo contrario, solo puede realizar una devolución local calificada).

 inline fun letIn(componentName: String?, values: List<LifeService.Value?>?, body: (String, List<LifeService.Value?>) -> Unit) { if (!TextUtils.isEmpty(componentName) && (values != null && values.isNotEmpty())) { body(componentName!!, values) } } 

… o si quieres que tenga receptores …

 inline fun String?.letIn(values: List<LifeService.Value?>?, body: String.(List<LifeService.Value?>) -> Unit) { if (!TextUtils.isEmpty(this) && (values != null && values.isNotEmpty())) { this!!.body(values) } } 

Cuando declara letIn como en inline , puede colocar return en su lambda sin quejarse el comstackdor. No es necesario que su function esté en inline si sus lambdas solo realizan declaraciones locales, pero debería tener un retorno calificado (por ejemplo, return@letIn ).

Su primer ejemplo se vería así …

 for (option in 0 until optionsSize) { val component = optionsGroup?.options?.get(option) component?.let { with(component) { presentation.letIn(values, { values -> if (this == LifeComponentViewType.CHECKBOX) { this.letIn(transformCheckBoxValues(optionsGroup), { data -> dataSource?.push(this, ComponentDataCheckBoxCollection(this, data)) view.buildComponent(this) return //returns from function }) } else { dataSource?.push(this, ComponentDataCollection(name, values)) view.buildComponent(this) return //returns from function } }) } } } 

Por último, tenga en count que si quería saltar de la lambda temprano, pero continúe un ciclo externo como en:

 fun test1() { val list = listOf("a", "b", "c") val optionsSize = 2 for(i in 0..optionsSize) loop@ { println("calliing list.forEach") list.forEach lit@ { if(it == "a") return@lit if(it == "c") return@loop println(it) } } } 

No funcionará Intelli-sense no se queja, pero el comstackdor arroja un error interno. Pero puedes convertir el loop externo en un lambda, y funciona …

 fun test() { val list = listOf("a", "b", "c") val optionsSize = 2 (0..optionsSize).forEach() loop@ { println("calliing list.forEach") list.forEach lit@ { if(it == "a") return@lit if(it == "c") return@loop println(it) } } } 

De nuevo, esto solo funciona si la function a la que se pasa el lambda se declara en inline (como por forEach inline se declara en inline ).

  • Akka stream, upstream no produce valores
  • ¿Cómo paso solo un parámetro a una function cuando espera dos?
  • Jna, Pointer ya asignado a la interfaz Proxy
  • ¿Cuáles son las palabras key reservadas en Kotlin?
  • ¿Lee el valor de la anotación de la function de Kotlin usando la reflexión?
  • Realm, findAllSorted y distinct
  • La cobertura de código de estudio de Android no muestra ninguna class de Kotlin
  • Sala: error al utilizar @Transaction
  • cómo limitar kotlin coroutines máxima concurrency
  • Kotlin: ¿Cómo verificar si enum contiene una cadena dada sin interferir con las excepciones?
  • señal 7 (SIGBUS), código 2 (BUS_ADRERR)