Cuándo usar los methods de extensión?

Estoy escribiendo el código de Kotlin y una de las características que tiene son los methods de extensión, que son efectivamente los mismos que las funciones normales, excepto que la syntax que utiliza parece una llamada a un método de instancia.

Función normal

fun blah(x: Int) { println(x) } val f = blah(1) 

Método de extensión

 fun Int.blah() { println(this) } val f = 1.blah() 

Por lo que yo entiendo, los methods de extensión de C # funcionan de manera similar.

En principio, literalmente, cualquier function no nula podría escribirse como un método de extensión moviendo el tipo del primer parámetro a la izquierda del nombre de la function y ajustando el cuerpo de la function y llamando a los sitios en consecuencia (como en este ejemplo).

¿Debo escribir todas mis funciones como methods de extensión, entonces? ¿Ninguno de ellos? ¿Qué principio debería usar para decidir qué funciones escribir normalmente y qué escribir como método de extensión de una de las inputs?

    https://kotlinlang.org/docs/reference/extensions.html#extensions-are-resolved-statically

    Las extensiones se resuelven estáticamente

    Las extensiones en realidad no modifican las classs que extienden. Al definir una extensión, no inserta nuevos miembros en una class, sino que simplemente hace que nuevas funciones se puedan llamar con la notación de puntos en variables de este tipo.

    Nos gustaría enfatizar que las funciones de extensión se despachan estáticamente , es decir, que no son virtuales por tipo de receptor

    Por lo tanto, escribir todas sus funciones como methods de extensión no sería un buen enfoque, ya que se envían estáticamente. Esto le quita la posibilidad de anularlos, por ejemplo, en classs derivadas.

    Es más como una opción de layout cuando hace una function de extensión o una function "normal".

    Te recomendaría lo siguiente: cuando tengas una function que escribirías como una function de utilidad con una class de utilidad como StringUtil.isNullOrEmpty(String) , usa las funciones de extensión. Use el rest como funciones "normales".

    Lea también la motivación de Kotlin para crear extensiones: https://kotlinlang.org/docs/reference/extensions.html#motivation

    Usted escribe extensiones cuando no tiene acceso al código fuente. En Java, escribe classs de utilidad.

     public final class BarUtility { public static int foo(Bar i, int j){ return i.value + j; } } BarUtility.foo(bar, 1); 

    En Kotlin, escribe el método de extensiones.

     fun Bar.foo(i: Int): Int = value + i bar.foo(1) 

    En C #, es lo mismo pero también lo usa para la implementación del método de interfaz. (Kotlin permite la implementación del método de interfaz).

    No hay una regla fija, pero no debe escribir todas sus funciones normales como methods de extensión.

    Se usan principalmente para dos cosas:

    Tipos extendidos sobre los que no tienes control directo. Un ejemplo común en C # es la function ForEach () que extiende IEnumerable (types básicos para lists, etc.) con un método para aplicar una acción a todos los elementos:

     public static void ForEach<T>(this IEnumerable<T> enumeration, Action<T> action) { foreach (T item in enumeration) { action(item); } } 

    Funciones de ayuda que simplifican las llamadas comunes a sus propias classs, pero no garantizan un método propio en su class o no quiere ser parte de su API.