¿Puedo enviar la function de extensión a través del parámetro de function?

Tengo algunas funciones de extensión a continuación.

fun EditText.setEmailValidationListener(): TextWatcher { val textWatcher = object : TextWatcher { override fun beforeTextChanged(text: CharSequence?, start: Int, count: Int, after: Int) { } override fun onTextChanged(text: CharSequence?, start: Int, before: Int, count: Int) { } override fun afterTextChanged(text: Editable?) { validateEmail() } private fun validateEmail(): Boolean { if (validateEmailFormat(showError = false)) { getParentInputLayout()?.isErrorEnabled = false return true } return false } } addTextChangedListener(textWatcher) return textWatcher } fun EditText.setPasswordValidationListener(): TextWatcher { val textWatcher = object : TextWatcher { override fun beforeTextChanged(text: CharSequence?, start: Int, count: Int, after: Int) { } override fun onTextChanged(text: CharSequence?, start: Int, before: Int, count: Int) { } override fun afterTextChanged(text: Editable?) { validateEmpty() } private fun validatePasswordText(): Boolean { if (validateEmptyText(showError = false)) { getParentInputLayout()?.isErrorEnabled = false return true } return false } } addTextChangedListener(textWatcher) return textWatcher } fun EditText.validateEmailFormat(showError: Boolean = true): Boolean { // Do something checking the Email return false } fun EditText.validatePasswordText(showError: Boolean = true): Boolean { // Do something checking the Password return false } private fun EditText.getParentInputLayout(): TextInputLayout? { if (parent is TextInputLayout) { return parent as TextInputLayout } return null } 

Tanto setEmailValidationListener como setPasswordValidationListener son idénticos, excepto por la function de validation que utilizan respectivamente, es decir validateEmailFormat y validatePasswordFormat .

Así que planeo refactorizar el código común de dos funciones en una function común como la siguiente

 fun EditText.setupTextChangeListener(validatorFunc : (showError: Boolean) -> Boolean): TextWatcher { val textWatcher = object : TextWatcher { override fun beforeTextChanged(text: CharSequence?, start: Int, count: Int, after: Int) { } override fun onTextChanged(text: CharSequence?, start: Int, before: Int, count: Int) { } override fun afterTextChanged(text: Editable?) { validateEmpty() } private fun validateEmpty(): Boolean { if (validatorFunc(false)) { getParentInputLayout()?.isErrorEnabled = false return true } return false } } addTextChangedListener(textWatcher) return textWatcher } 

… donde básicamente es solo para enviar validationFunc como parámetro para ello.

Sin embargo, no puedo encontrar ninguna forma de enviar EditText.validateEmailFormat y EditText.validatePasswordFormat al parámetro de function validationFunc .

¿Cómo podría lograr eso?

Alguna teoría

La firma de las funciones de extensión es un poco más complicada de lo que se puede ver al principio. La extensión necesita tener alguna reference al object de esta class para poder actuar sobre ella.

De hecho, el método de extensión

 fun EditText.validateEmailFormat(showError: Boolean = true): Boolean 

después de descomstackr en Java antiguo, se ve así:

 public static final boolean validateEmailFormat(@NotNull EditText $receiver, boolean showError) 

Como es (casi) imposible cambiar la class de Java ya comstackda. Así que Kotlin (y posiblemente otros lenguajes que tienen un concepto de methods de extensión) utiliza methods estáticos, con el primer parámetro que es el receptor de la class que se extiende, para que funcione.

Regreso al negocio

Su validateEmailFormat es de hecho de tipo EditText.(Boolean) -> Boolean y al mismo time es de tipo (EditText, Boolean) -> Boolean . Entonces debes hacer una de estas dos cosas:

Primero puede hacer que EditText.setupTextChangeListener acepte validatorFunc como EditText.(Boolean) -> Boolean o (EditText, Boolean) -> Boolean lugar de (Boolean) -> Boolean .

O puede abstenerse de extender EditText en el modo fun EditText.validateEmailFormat(Boolean) y dejar en claro la function de Kotlin, por ejemplo, algo así como fun EditText.validateEmailFormat(Boolean) fun validateEmailFormat(String, Boolean) .

Como está utilizando ampliamente las funciones de extensión, asumo que la primera opción es la solución correcta para usted.

  • La function de extensión no crea un nuevo object Observable
  • ¿Cómo se pueden agregar methods estáticos a las classs de Java en Kotlin?
  • Kotlin class NoClassDefFoundError crash
  • Comtesting si mi actividad está en MultiWindowMode o no está usando Kotlin
  • Función de extensión booleana
  • acceso al método de extensión kotlin en otro kt
  • Kotlin - Extensión para la class final
  • Choque de extensión Kotlin
  • ¿Se debe evitar nombrar una function igual que una class existente en Kotlin? ¿Por qué?
  • Kotlin crea problemas con Android
  • ¿Cómo verificar la class "instanceof" en kotlin?