Swift-style-guide: Funciones frente a métodos

Creado en 6 jul. 2015  ·  26Comentarios  ·  Fuente: raywenderlich/swift-style-guide

La guía debe ser explícita sobre el uso apropiado de la función y el método al escribir. Habiendo echado un vistazo a los documentos del lenguaje de programación Swift de Apple, algo como:

Un método es una función que está asociada con una clase, estructura o enumeración. Esto se aplica tanto a los métodos de instancia como a los de tipo. Una función, por otro lado, se declara en el ámbito global y no pertenece a ningún tipo.

sería suficiente.

Comentario más útil

Qué tal algo como esto:

Métodos vs funciones libres

Los métodos son funciones asociadas con un tipo y se prefieren debido a su capacidad de descubrimiento de autocompletar. Las funciones libres son menos comunes pero tienen sentido cuando una operación no está estrechamente asociada con un tipo o instancia en particular.

Privilegiado

let sorted = items.mergeSort()  // easily discoverable
rocket.launch()  // a mutating method

No preferido

let sorted = mergeSort(items)
launch(&rocket)

Excepciones de función libre

let tuples = zip(a, b)  // feels natural as a free function (symmetry)
let value = max(x,y,z)  // another free function that feels natural

Todos 26 comentarios

También he visto funciones denominadas "funciones gratuitas". Supongo que "gratis" significa "no asociado con ningún objeto".

Las funciones tienen más opciones de alcance que tipo y global, en Swift.

Simplemente asumí que los métodos normales en Objective-C ahora se denominan functiona en Swift . Todo el material que he leído en términos de foros, blogs, tutoriales, etc. se ha referido a ellos simplemente como functions , incluso cuando pertenecen a una clase o enumeración.

@mitchellporter Los propios documentos de Apple son claros sobre cuándo se debe hacer referencia a algo como una función o un método, según la cita anterior.

Los tutoriales en raywenderlich.com también siguen las pautas de Apple aquí, por lo que deberían incluirse en la guía de estilo.

También hay funciones y métodos en Objective-C; no todo es un método. 😉

@micpringle Tiene sentido, pero juro que he leído mucho material en el que simplemente lo llaman function incluso cuando pertenece a una clase. Supongo que tampoco soy el único que siempre usa function , será interesante ver si esto cambia en el futuro.

¿Son las "funciones" dentro de los métodos "métodos anidados"?
¿Cómo se llaman las funciones dentro de los cierres u otras no funciones?

struct Struct {
   let closure = {
      func whoAmI() {}
   }

   var any: Any? {
      func jeanValjean() {}
      return nil
   }
}

Creo que estas se clasificarían como funciones anónimas (IMO) ya que técnicamente no "pertenecen" a nada, y solo existen dentro de ese alcance particular y no se puede acceder a ellas desde fuera de él.

No creo que "función anónima" sea el nombre correcto aquí, que generalmente se refiere a cierres.

Yo las llamaría "funciones anidadas": "funciones" porque son funciones, no métodos adjuntos a un tipo o instancia con nombre. Y "anidados" porque ... ¡están anidados! Quizás "funciones de alcance", pero eso no parece tan claro.

Disculpas, no me di cuenta de que los cierres también se conocen como funciones anónimas. :]

Las funciones anidadas me suenan bien. Estoy de acuerdo en que la mira telescópica no suena del todo bien.

Creo que las "funciones anidadas" dentro de cualquier cosa, ya sea un método o no, parecen lo suficientemente claras para el futuro previsible.

Y aunque creo que las funciones anidadas que tienen nombres las hacen "anónimas", no tengo claro qué es exactamente "anónimo", sin embargo, cuando se trata de cierres, especialmente los almacenados, inmutables, que son muy parecidos a funciones. Me inclino a creer que la función almacenada es de hecho anónima, pero el cierre que la captura, y potencialmente algún estado, es lo que tiene el nombre. Esa es la forma en que se enseña para C #, donde la sintaxis lambda es una forma abreviada de construir lo que llama un delegado.
https://msdn.microsoft.com/en-us/library/system.delegate (v = frente a 110) .aspx

func nonymous() {
   func nonymous() {}
}

let anonymouses: [() -> ()] = [].map
{$0} // This "transform" is also anonymous.

let unlcearToMeWhetherNonymous = {}

Es un punto sutil y posiblemente incluso discutible una vez que llegas a las entrañas de Swift y todo es igual, pero declarar algo con func definitivamente le da un nombre a la cosa. Por el contrario, un cierre es solo un bloque de código sin nombre. Puede asignarlo a una variable o constante, por supuesto, pero eso es solo almacenar un puntero a la cosa.

Nuevamente, es una especie de diferencia artificial. Podrías ser como un ceceo y decir que func es simplemente azúcar sintáctico para darle un nombre a un cierre.

Qué tal algo como esto:

Métodos vs funciones libres

Los métodos son funciones asociadas con un tipo y se prefieren debido a su capacidad de descubrimiento de autocompletar. Las funciones libres son menos comunes pero tienen sentido cuando una operación no está estrechamente asociada con un tipo o instancia en particular.

Privilegiado

let sorted = items.mergeSort()  // easily discoverable
rocket.launch()  // a mutating method

No preferido

let sorted = mergeSort(items)
launch(&rocket)

Excepciones de función libre

let tuples = zip(a, b)  // feels natural as a free function (symmetry)
let value = max(x,y,z)  // another free function that feels natural

Con respecto a,

Excepciones de función libre

let tuples = zip(a, b)  // feels natural as a free function (symmetry)
let value = max(x,y,z)  // another free function that feels natural

"Se siente natural" es bastante ambiguo y subjetivo.

¿Podemos aclarar lo que queremos decir aquí?

Además, tanto zip como max también sufrirían el problema de // hard to discover que mencionaste en el PR.

En mi humilde opinión, creo que zip es un ejemplo incómodo. Problemas que tengo con él:

  • ¿Qué está haciendo realmente? Combinando a y b ? ¿Comprimir a y b alguna manera? ¿Algo más? Sin más contexto, es difícil saberlo.

En vez de

Las funciones libres son menos comunes pero tienen sentido cuando una operación no está estrechamente asociada con un tipo o instancia en particular.

¿Qué tal esto?

Las funciones gratuitas, que no están asociadas a una clase o tipo, deben usarse con moderación. Cuando sea posible, prefiera utilizar un método en lugar de una función gratuita. Esto ayuda a la legibilidad y la visibilidad.

Las funciones libres son más apropiadas cuando no están asociadas con ningún tipo o instancia en particular.

Reabriré este número para buscar más discusión sobre Free Function Exceptions .

Bueno, esta es una función de biblioteca estándar. Tiene precedencia en lenguajes como R, Python, C #, C ++. (A través de boost).

Bueno, esta es una función de biblioteca estándar.

¿En serio? No lo he usado en iOS ... * avergonzado *

Lo comprobaré ... Si se entiende / usa ampliamente en iOS, tal vez mi preocupación aquí esté fuera de lugar ...

Me gusta tu sugerencia de verborrea ... Soy reacio a renunciar al ejemplo del zip. (PD: El equipo RW Swift tiene una carta que es más grande (o más pequeña) que iOS).

El equipo RW Swift tiene una carta que es más grande (o más pequeña) que iOS.

👍 Cierto. ;]

Después de revisar lo que hace zip , lo dejo como ejemplo. 👍

Disculpas por mi experiencia Swift-newbie-moment aquí. 😉

No hay problema. Gracias por tu ayuda, como siempre. Por cierto, acabo de notar que no se menciona en los créditos. Yo también lo arreglaré.

No estoy seguro de que las funciones gratuitas sean la mejor solución. Si se utilizan, creo que deberían agregar funciones que no se tratan en ningún otro lugar.

max

let max = Swift.max(0, 1, 2)
let maxElement = [0, 1, 2].maxElement()!

maxElement debería ser una propiedad y no un método, pero sigo pensando que la función gratuita es redundante. Si estos no se compilan para lo mismo, creo que el compilador debería mejorarse, pero incluso si no, no creo que el rendimiento importe nunca; No creo que la gente esté usando la función max con muchos elementos.

Código Postal
En C #, zip se implementa el equivalente a un método de extensión de protocolo Swift . No creo que sea mejor, pero es un ejemplo de cómo manejar zip diferente.

En Swift, zip es lo mismo que este inicializador para Zip2Sequence . Sería bueno tener una forma de representar una secuencia comprimida de un número variable de secuencias de entrada, pero hasta que eso suceda, creo que usar el inicializador directamente está bien.

zip([1...3], ["a"..."c"])
Zip2Sequence([1...3], ["a"..."c"])

operadores
La gran mayoría de las funciones gratuitas que he escrito en Swift son operadores. He visto a Chris Lattner y Joe Groff sugiriendo que los operadores podrán definirse dentro de tipos, a la C #, en el futuro, por lo que los operadores también pueden seguir las convenciones que se elijan, para otras funciones, entonces. Su implementación actual como solo función libre probablemente no debería usarse como una guía.

operadores
La gran mayoría de las funciones gratuitas que he escrito en Swift son operadores. He visto a Chris Lattner y Joe Groff sugiriendo que los operadores podrán definirse dentro de tipos, a la C #, en el futuro ...

Sí, es probable que esta sea la dirección en la que Swift se mueva en el futuro. Aquí hay una propuesta bastante reciente de Chris Lattner, como mencionaste.

Esto es especialmente peculiar con protocolos como Equatable , que según nuestras pautas de extensión, esencialmente _requieren_ que cree una extensión vacía. Esto es incómodo en el mejor de los casos. 😞

Definitivamente estoy de acuerdo en que los operadores no deben usarse como ejemplo de funciones gratuitas ideales.

¡Gracias por los comentarios @ Jessy-!

Algunas notas:

Creo que maxElement() se declara un método porque no es O (1), lo que podría sorprender a algunos usuarios. Si implementa una propiedad que no es O (1), debe estar claramente documentada. (En los tutoriales de RW tenemos el lujo de que todo el código está a la vista, por lo que no tenemos que preocuparnos tanto por eso o aplicarlo como una guía de estilo).

Por otro lado, algunas formas de max<T: Comparable> son O (1) y tienen el potencial de especializarse para aprovechar el hardware. (Supongo que es por eso que hay una versión de dos parámetros además de la versión variadic, aunque no lo he confirmado).

En cualquier caso, creo que todos estamos de acuerdo en que las funciones gratuitas deben usarse con moderación, pero yo rechazaría _nunca_. Los ejemplos utilizados provienen de la biblioteca estándar. No he visto ninguna propuesta para eliminar la función zip de la biblioteca estándar. ¿Hay objeciones a los detalles de la nueva redacción de @ JRG-Developer o la solicitud de extracción combinada actualmente módulo esta nueva redacción?

Siéntase libre de reabrir si cree que hay algo más que deba discutirse. (Combinado con la rama de actualización).

¿Fue útil esta página
0 / 5 - 0 calificaciones

Temas relacionados

icanzilb picture icanzilb  ·  6Comentarios

agirault picture agirault  ·  3Comentarios

designatednerd picture designatednerd  ·  22Comentarios

sima-11 picture sima-11  ·  5Comentarios

rayfix picture rayfix  ·  3Comentarios