Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

207
Visualizações
¿Cómo puedo ceder en una secuencia generada recursivamente?

Tengo una función que genera valores. Lo hace llamándose recursivamente a sí mismo, y cada vez que se alcanza el caso base, se emite un valor. Este es solo un ejemplo de juguete, el real es mucho más complicado y, por lo tanto, más difícil de transformar en algo no recursivo.

Me gustaría hacer esto como una secuencia. Pero hacer esto no se compilará en la línea que cedo, con el mensaje

Las funciones de suspensión solo se pueden llamar dentro del cuerpo coroutine

Aquí está el intento:

 fun test1() = sequence { fun a(i: Int) { if (i > 4) { yield(i) // <- fails to compile } else { a(i + 1) a(i + 2) a(i + 3) } } a(1) }

Si trato de agregar la palabra clave suspend a la función a , obtengo el error

Las funciones de suspensión restringidas solo pueden invocar funciones de suspensión de miembros o extensiones en su ámbito de rutina restringido

Puedo hacer que funcione, devolviendo todos los valores y haciendo un yieldAll. Sin embargo, el problema con esto es que necesita hacer todo el cálculo y mantener todos los resultados en la memoria antes de que se pueda usar la secuencia. Para mi caso, esto no funcionará porque me quedaría sin memoria, o incluso puede tener una cantidad casi infinita de resultados donde solo quiero tomar algunos.

Así que esto funciona, pero no es óptimo.

 fun test2() = sequence { fun a(i: Int): List<Int> { if (i > 4) { return listOf(i) } else { return listOf( a(i + 1), a(i + 2), a(i + 3) ).flatten() } } yieldAll(a(1)) }

¿Alguna idea sobre cómo combinar secuencias con una función recursiva, lo que me permite generar valores sin precomputar y asignar memoria para todos ellos?

over 4 years ago · Santiago Trujillo
2 Respostas
Responde à pergunta

0

¿Qué tal hacer a devolución en una Sequence perezosa?

 fun a(i: Int): Sequence<Int> = sequence { if (i > 4) { // println("yielding $i") yield(i) } else { yieldAll(a(i + 1)) // this yieldAll is lazy yieldAll(a(i + 2)) yieldAll(a(i + 3)) } } fun test1() = a(1)

Si descomentas el println y recorres la secuencia, verás que es perezoso:

 for (i in test1()) { println("printing $i") }

Producción:

 yielding 5 printing 5 yielding 6 printing 6 yielding 7 printing 7 yielding 5 printing 5 yielding 6 printing 6 yielding 5 printing 5 yielding 6 printing 6 yielding 7 printing 7 ...
over 4 years ago · Santiago Trujillo Relatório

0

Puede convertir la función interna en una función de suspensión que es una extensión de SequenceScope. El generador de secuencias utiliza un tipo especial de corrutina que se limita a llamar únicamente a las extensiones de función de suspensión de SequenceScope. Presumiblemente, esto se debe a que las secuencias están destinadas a usarse solo como iterables sincrónicos y sin suspensión. Dado que yield() es una de estas funciones de suspensión de SequenceScope, debe hacer que su función también sea una función de extensión de suspensión.

 fun test1() = sequence { suspend fun SequenceScope<Int>.a(i: Int) { if (i > 4) { yield(i) } else { a(i + 1) a(i + 2) a(i + 3) } } a(1) }
over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda