Error de compilation llamando a un método de extensión desde otro método de extensión en Kotlin

Cuando trato de llamar a un método de extensión desde otro método de extensión (sobrecargando ese método) no se comstack en IntelliJ 14.1.5 y Kotlin 0.14.449

Como soy nuevo en el lenguaje y en la reference, no se prohíbe hacerlo; me gustaría saber:

  • ¿Es posible llamar a un método de extensión desde otro método de extensión?
  • ¿La syntax que uso es correcta (y, por lo tanto, es un error)?
  • Si no, ¿cuál es la syntax correcta?

Este es el código que no comstack:

fun String.replace (prefix: String, suffix: String, vararg parameters: Pair<String, String>) = parameters.fold(this, { result, pair -> result.replace (prefix + pair.first + suffix, pair.second) }) fun String.replace (vararg parameters: Pair<String, String>) = this.replace ("", "", parameters) 

¡Gracias por adelantado!

Hay otras respuestas, pero aquí hay más notas sobre lo que está sucediendo y una solución similar que mantiene el nombre del método, evita la recursión y mantiene varargs para ambas firmas de methods:

  • Al pasar una varargs a otra, necesita usar el operador de propagación porque las varargs se reciben como una matriz, quiere convertirlas nuevamente en una list de parameters y el operador de propagación lo hace.

  • La llamada dentro de fold() lambda accidentalmente se llama a sí misma. Como llama a string.replace() con 2 parameters, ¿qué versión gana? La versión string.replace(String, String, vararg Pair<String,String>) o string.replace(String, String, Boolean[defaulted to false]) ? Ambos se ven iguales cuando solo se llama con 2 parameters. Y el local gana y, por lo tanto, tiene recursion. Para forzar una llamada a la function de sustitución stdlib, el 3er parámetro se convierte en false por defecto, así que pase ese valor específicamente para que se encuentre la firma correcta del método.

Código de trabajo:

 fun String.replace(prefix: String, suffix: String, vararg parameters: Pair<String, String>) { parameters.fold(this) { result, pair -> // add a last parameter to differentiate what version I want called, the one with optional // boolean parameter last (ignoreCase: Boolean = false). Otherwise this recurses on accident. result.replace(prefix + pair.first + suffix, pair.second, false) } } fun String.replace(vararg parameters: Pair<String, String>) { this.replace ("", "", *parameters) // add * spread operator } 

Su problema es que el primer String.replace se llama recursivamente y nunca se alcanza el String.replace principal. Además, el vararg en el segundo pasa al primero como una matriz> por lo que llamar a la segunda function nunca coincidirá con la primera.

 fun String.replace(vararg parameters: Pair<String, String>) = this.replace("", "", parameters) fun String.replace(prefix: String, suffix: String, parameters: Array<out Pair<String, String>>) = parameters.fold(this, { result, pair -> result.replace(prefix + pair.first + suffix, pair.second) }) 

Como pensé que era un error, busqué en el rastreador de problemas de Kotlin y encontré esto: https://youtrack.jetbrains.com/issue/KT-2079

La syntax correcta para pasar un argumento vararg a otra function está usando un asterisco '*':

 fun String.filter (prefix: String, suffix: String, vararg parameters: Pair<String, String>) = parameters.fold(this, { result, pair -> result.replace (prefix + pair.first + suffix, pair.second) }) fun String.filter (vararg parameters: Pair<String, String>) = this.filter("", "", *parameters) 
  • Recolectando artículos con las transmisiones de Kotlin
  • Emitir matriz de bytes a Json con Fuel and Result
  • Error al convertir bytecode - DexException - Firebase Auth
  • ¿Cómo puedo verificar el tipo genérico en Kotlin?
  • Accediendo al campo de una instancia diferente de la misma class en Kotlin
  • Debería hashCode () devolver el ID único de un object
  • Kotlin: ¿es posible tener una propiedad constante dependiente de un tipo genérico de implementación?
  • El depurador Java seleccionado actualmente no admite puntos de interrupción de tipo 'Kotlin Line Breakpoints'
  • Patrón Regex Kotlin
  • ¿Cómo puedo generar un parámetro constructor del tipo "Unidad" de Kotlin con un parámetro de tipo único con kotlinpoet?
  • Spring no puede manejar el método que devuelve la class Kotlin interna genérica