Swift-style-guide: Fonctions vs méthodes

Créé le 6 juil. 2015  ·  26Commentaires  ·  Source: raywenderlich/swift-style-guide

Le guide doit être explicite sur l'utilisation appropriée de la fonction et de la méthode lors de l'écriture. Après avoir jeté un œil à la documentation du langage de programmation Swift d'Apple, quelque chose comme :

Une méthode est une fonction associée à une classe, une structure ou une énumération. Cela vaut pour les méthodes d'instance et de type. Une fonction, en revanche, est déclarée dans la portée globale et n'appartient à aucun type.

serait suffisant.

Commentaire le plus utile

Que diriez-vous quelque chose comme ça:

Méthodes vs fonctions libres

Les méthodes sont des fonctions associées à un type et préférées en raison de leur capacité de découverte automatique. Les fonctions libres sont moins courantes mais ont du sens lorsqu'une opération n'est pas étroitement associée à un type ou une instance particulière.

Préféré

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

Pas préféré

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

Exceptions de fonction gratuites

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

Tous les 26 commentaires

J'ai également vu des fonctions appelées "fonctions libres". Je suppose que "libre" signifie "non associé à un objet".

Les fonctions ont plus d'options de portée que type et global, dans Swift.

Je viens de supposer que les méthodes normales dans Objective-C étaient maintenant appelées functiona dans Swift . Tout le matériel que j'ai lu en termes de forums, de blogs, de tutoriels, etc. les appelle simplement functions , même lorsqu'ils appartiennent à une classe ou à une énumération.

@mitchellporter Les propres documents d'Apple

Les tutoriels sur raywenderlich.com suivent également les directives d'Apple ici, c'est pourquoi il devrait être intégré au guide de style.

Il y a aussi des fonctions et des méthodes en Objective-C ; tout n'est pas une méthode. ??

@micpringle C'est logique, mais je jure que j'ai lu beaucoup de documents où ils l'appellent simplement un function même s'il appartient à une classe. Je suppose que je ne suis pas le seul à utiliser toujours function non plus, ce sera intéressant de voir si cela change à l'avenir.

Les « fonctions » à l'intérieur des méthodes sont-elles des « méthodes imbriquées » ?
Comment s'appellent les fonctions à l'intérieur des fermetures ou d'autres non-fonctions ?

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

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

Je pense que celles-ci seraient classées comme des fonctions anonymes (IMO) car elles n'appartiennent techniquement à rien, et elles n'existent que dans cette portée particulière et ne sont pas accessibles de l'extérieur.

Je ne pense pas que "fonction anonyme" soit le bon nom ici - cela fait généralement référence aux fermetures.

Je les appellerais "fonctions imbriquées": "fonctions" car ce sont des fonctions, pas des méthodes attachées à un type ou à une instance nommés. Et "nichées" parce que... elles sont imbriquées ! Peut-être des "fonctions étendues" mais cela ne semble pas aussi clair.

Mes excuses, je n'avais pas réalisé que les fermetures étaient également appelées fonctions anonymes. :]

Les fonctions imbriquées me semblent bonnes. Je suis d'accord que la portée ne sonne pas tout à fait juste.

Je pense que les "fonctions imbriquées" à l'intérieur de n'importe quoi, que ce soit une méthode ou non, semblent assez claires dans un avenir prévisible.

Et bien que je pense que les fonctions imbriquées ayant des noms les rendent "anonymes", je ne sais pas exactement ce qui est "anonyme", cependant, en ce qui concerne les fermetures, en particulier celles stockées et immuables, qui ressemblent beaucoup à des fonctions. Je penche pour croire que la fonction stockée est en effet anonyme, mais la fermeture qui la capture, et potentiellement un état, est ce qui porte le nom. C'est ainsi qu'on l'enseigne pour C#, où la syntaxe lambda est un raccourci pour construire ce qu'elle appelle un délégué.
https://msdn.microsoft.com/en-us/library/system.delegate (v=vs.110).aspx

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

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

let unlcearToMeWhetherNonymous = {}

C'est un point subtil et peut-être même discutable une fois que vous descendez dans les entrailles de Swift et que tout est pareil, mais déclarer quelque chose avec func donne définitivement un nom à la chose. En revanche, une fermeture n'est qu'un bloc de code sans nom. Vous pouvez bien sûr l'affecter à une variable ou à une constante, mais il s'agit simplement de stocker un pointeur vers la chose.

Encore une fois, c'est une sorte de différence artificielle. Vous pourriez être du genre lisp et dire que func n'est que du sucre syntaxique pour donner un nom à une fermeture.

Que diriez-vous quelque chose comme ça:

Méthodes vs fonctions libres

Les méthodes sont des fonctions associées à un type et préférées en raison de leur capacité de découverte automatique. Les fonctions libres sont moins courantes mais ont du sens lorsqu'une opération n'est pas étroitement associée à un type ou une instance particulière.

Préféré

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

Pas préféré

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

Exceptions de fonction gratuites

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

Concernant,

Exceptions de fonction gratuites

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

« Feels natural » est assez ambigu et subjectif.

Pouvons-nous clarifier ce que nous entendons ici?

De plus, zip et max souffriraient également du problème // hard to discover vous avez soulevé dans le PR.

IMHO, je pense que zip est un exemple maladroit. Problèmes que j'ai avec :

  • Qu'est-ce que _fait_ en fait ? Combiner a et b ? Compresser a et b manière ou d'

À la place de

Les fonctions libres sont moins courantes mais ont du sens lorsqu'une opération n'est pas étroitement associée à un type ou une instance particulière.

Que dis-tu de ça?

Les fonctions libres, qui ne sont pas attachées à une classe ou à un type, doivent être utilisées avec parcimonie. Lorsque cela est possible, préférez utiliser une méthode plutôt qu'une fonction libre. Cela facilite la lisibilité et la découvrabilité.

Les fonctions libres sont plus appropriées lorsqu'elles ne sont associées à aucun type ou instance particulier.

Je rouvre ce problème pour poursuivre la discussion sur Free Function Exceptions .

Eh bien, c'est une fonction de bibliothèque standard. Il a la priorité dans les langages tels que R, Python, C#, C++.(via boost).

Eh bien, c'est une fonction de bibliothèque standard.

Ah bon? Je ne l'ai pas utilisé sous iOS... *gêné*

Je vais vérifier... Si c'est largement compris/utilisé sur iOS, peut-être que ma préoccupation ici est déplacée...

J'aime votre suggestion de verbiage... Je suis réticent à abandonner l'exemple zip. (PS : L'équipe RW Swift a une charte qui est plus grande (ou plus petite) qu'iOS.)

L'équipe RW Swift a une charte qui est plus grande (ou plus petite) qu'iOS.

Vrai. ;]

Après avoir examiné ce que fait zip , je suis pour le laisser à titre d'exemple. ??

Toutes mes excuses pour mon expérience Swift-newbie-moment ici. ??

Pas de soucis. Merci pour votre aide comme toujours. BTW, je viens de remarquer que vous n'êtes pas mentionné dans le générique. Je vais corriger ça aussi.

Je ne suis pas sûr que les fonctions gratuites soient toujours la meilleure solution. S'ils sont utilisés, je pense qu'ils devraient ajouter des fonctionnalités qui ne sont pas abordées ailleurs.

max

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

maxElement devrait être une propriété et non une méthode, mais je pense toujours que la fonction gratuite est redondante. Si ceux-ci ne compilent pas sur la même chose, alors je pense que le compilateur devrait être amélioré, mais même si ce n'est pas le cas, je ne pense pas que les performances auront jamais d'importance ; Je ne pense pas que les gens utiliseraient la fonction max avec de nombreux éléments.

Zip *: français
En C#, zip est implémenté comme l'équivalent d'une méthode d'extension de protocole Swift . Je ne pense pas que ce soit mieux, mais c'est un exemple de la façon de gérer différemment zip .

Dans Swift, zip est la même chose que cet initialiseur pour Zip2Sequence . Ce serait bien d'avoir un moyen de représenter une séquence zippée d'un nombre variable de séquences d'entrée, mais jusqu'à ce que cela se produise, je pense qu'utiliser directement l'initialiseur est bien.

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

les opérateurs
La grande majorité des fonctions libres que j'ai écrites dans Swift sont des opérateurs. J'ai vu Chris Lattner et Joe Groff suggérer que les opérateurs pourront être définis dans des types, à la C#, à l'avenir, donc les opérateurs pourront également suivre les conventions choisies, pour d'autres fonctions, alors. Leur implémentation actuelle en tant que fonction libre uniquement ne devrait probablement pas être utilisée comme ligne directrice.

les opérateurs
La grande majorité des fonctions libres que j'ai écrites dans Swift sont des opérateurs. J'ai vu Chris Lattner et Joe Groff suggérer que les opérateurs pourront être définis dans les types, à la C#, à l'avenir...

Oui, c'est probablement la direction que prendra Swift à l'avenir. Voici une proposition assez récente de Chris Lattner, comme vous l'avez mentionné.

Ceci est particulièrement particulier avec des protocoles comme Equatable , qui, selon nos directives d'extension, vous obligent essentiellement à créer une extension vide. C'est au mieux gênant. ??

Je suis tout à fait d'accord pour dire que les opérateurs ne doivent

Merci pour les commentaires @Jessy- !

Quelques notes:

Je pense que maxElement() est déclaré une méthode car ce n'est pas O(1), ce qui pourrait surprendre certains utilisateurs. Si vous implémentez une propriété qui n'est pas O(1), elle doit être clairement documentée. (Dans les didacticiels RW, nous avons le luxe que tout le code est à l'air libre, nous n'avons donc pas à nous en soucier autant ou à l'appliquer en tant que directive de style.)

D'un autre côté, certaines formes de max<T: Comparable> sont en O(1) et ont le potentiel d'être spécialisées pour tirer parti du matériel. (Je suppose que c'est pourquoi il existe une version à deux paramètres en plus de la version variadique bien que je ne l'ai pas confirmé.)

En tout cas, je pense que nous sommes tous d'accord pour dire que les fonctions libres doivent être utilisées avec parcimonie mais je repousserais _jamais_. Les exemples utilisés proviennent de la bibliothèque standard. Je n'ai vu aucune proposition pour supprimer la fonction zip de la bibliothèque standard. Y a-t-il des objections aux spécificités de la reformulation de @JRG-Developer ou à la demande de tirage actuellement fusionnée modulo cette reformulation ?

N'hésitez pas à rouvrir si vous pensez qu'il y a quelque chose de plus à discuter. (Fusionné avec la branche de mise à jour.)

Cette page vous a été utile?
0 / 5 - 0 notes

Questions connexes

sima-11 picture sima-11  ·  5Commentaires

fabienwarniez picture fabienwarniez  ·  9Commentaires

icanzilb picture icanzilb  ·  6Commentaires

gokselkoksal picture gokselkoksal  ·  9Commentaires

WingYn picture WingYn  ·  15Commentaires