Swift-style-guide: Funktionen vs. Methoden

Erstellt am 6. Juli 2015  ·  26Kommentare  ·  Quelle: raywenderlich/swift-style-guide

Der Leitfaden sollte die angemessene Verwendung von Funktion und Methode beim Schreiben explizit machen. Nachdem Sie sich die Dokumentation zur Swift-Programmiersprache von Apple angesehen haben, etwa:

Eine Methode ist eine Funktion, die einer Klasse, Struktur oder Aufzählung zugeordnet ist. Dies gilt sowohl für Instanz- als auch für Typmethoden. Eine Funktion hingegen wird im globalen Gültigkeitsbereich deklariert und gehört keinem Typ an.

würde ausreichen.

Hilfreichster Kommentar

Wie wäre es mit so etwas:

Methoden vs. freie Funktionen

Methoden sind Funktionen, die einem Typ zugeordnet sind und aufgrund ihrer automatischen Vervollständigung bevorzugt werden. Freie Funktionen sind weniger verbreitet, aber sinnvoll, wenn eine Operation nicht eng mit einem bestimmten Typ oder einer bestimmten Instanz verknüpft ist.

Bevorzugt

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

Nicht bevorzugt

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

Kostenlose Funktionsausnahmen

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

Alle 26 Kommentare

Ich habe auch Funktionen gesehen, die als "freie Funktionen" bezeichnet werden. Ich gehe davon aus, dass "frei" "mit keinem Objekt verbunden" bedeutet.

Funktionen haben in Swift mehr Bereichsoptionen als Typ und Global.

Ich habe einfach angenommen, dass normale Methoden in Objective-C jetzt als functiona in Swift . Das gesamte Material, das ich in Bezug auf Foren, Blogs, Tutorials usw. gelesen habe, hat sie einfach als functions , selbst wenn sie zu einer Klasse oder einer Aufzählung gehören.

@mitchellporter In Apples eigenen Dokumenten ist klar, wann etwas als Funktion oder Methode bezeichnet werden sollte, wie im obigen Zitat angegeben.

Tutorials auf raywenderlich.com folgen auch hier den Richtlinien von Apple, weshalb es in den Styleguide einfließen sollte.

Auch in Objective-C gibt es sowohl Funktionen als auch Methoden; nicht alles ist eine Methode. 😉

@micpringle Macht Sinn, aber ich schwöre, ich habe viel Material gelesen, in dem es einfach als function selbst wenn es zu einer Klasse gehört. Ich schätze, ich bin auch nicht der Einzige, der immer function . Es wird interessant sein zu sehen, ob sich dies in Zukunft ändert.

Sind "Funcs" innerhalb von Methoden "verschachtelte Methoden"?
Wie heißen Funktionen innerhalb von Closures oder anderen Nicht-Funktionen?

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

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

Ich denke, diese würden als anonyme Funktionen (IMO) eingestuft, da sie technisch gesehen zu nichts "gehören", und sie existieren nur innerhalb dieses bestimmten Bereichs und können nicht von außerhalb darauf zugegriffen werden.

Ich glaube, "anonyme Funktion" ist hier nicht der richtige Name - das bezieht sich normalerweise auf Verschlüsse.

Ich würde sie "verschachtelte Funktionen" nennen: "Funktionen", weil es sich um Funktionen handelt, nicht um Methoden, die an einen benannten Typ oder eine Instanz angehängt sind. Und "verschachtelt", weil... sie verschachtelt sind! Vielleicht "bereichsbezogene Funktionen", aber das scheint nicht so klar zu sein.

Entschuldigung, ich wusste nicht, dass Schließungen auch als anonyme Funktionen bezeichnet werden. :]

Verschachtelte Funktionen klingen für mich gut. Ich stimme zu, dass Scoped nicht ganz richtig klingt.

Ich denke, "verschachtelte Funktionen" in allem, sei es eine Methode oder nicht, scheinen für die absehbare Zukunft klar genug zu sein.

Und obwohl ich denke, dass verschachtelte Funktionen mit Namen sie "anonym" machen, ist mir unklar, was genau "anonym" ist, wenn es um Schließungen geht, insbesondere gespeicherte, unveränderliche, die Funktionen sehr ähnlich sind. Ich neige dazu zu glauben, dass die gespeicherte Funktion tatsächlich anonym ist, aber die Schließung, die sie erfasst, und möglicherweise ein Zustand, hat den Namen. So wird es für C# gelehrt, wo die Lambda-Syntax eine Abkürzung für die Konstruktion eines so genannten Delegierten ist.
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 = {}

Es ist ein subtiler Punkt und möglicherweise sogar ein strittiger Punkt, sobald Sie in die Eingeweide von Swift geraten und alles gleich ist, aber etwas mit func deklarieren, gibt dem Ding definitiv einen Namen. Im Gegensatz dazu ist eine Closure nur ein Codeblock ohne Namen. Sie könnten es natürlich einer Variablen oder Konstanten zuweisen, aber das ist nur ein Zeiger auf das Ding.

Auch hier ist es ein künstlicher Unterschied. Sie könnten ganz lispelnd sein und sagen, dass func nur syntaktischer Zucker ist, um einem Verschluss einen Namen zu geben.

Wie wäre es mit so etwas:

Methoden vs. freie Funktionen

Methoden sind Funktionen, die einem Typ zugeordnet sind und aufgrund ihrer automatischen Vervollständigung bevorzugt werden. Freie Funktionen sind weniger verbreitet, aber sinnvoll, wenn eine Operation nicht eng mit einem bestimmten Typ oder einer bestimmten Instanz verknüpft ist.

Bevorzugt

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

Nicht bevorzugt

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

Kostenlose Funktionsausnahmen

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

Hinsichtlich,

Kostenlose Funktionsausnahmen

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

"Fühlt sich natürlich an" ist ziemlich zweideutig und subjektiv.

Können wir klarstellen, was wir hier meinen?

Außerdem würden sowohl zip als auch max unter dem // hard to discover Problem leiden, das Sie in der PR angesprochen haben.

IMHO, ich denke, dass zip ein unangenehmes Beispiel ist. Probleme die ich damit habe:

  • Was _tun_ sie eigentlich? Kombination von a und b ? Komprimieren von a und b irgendwie? Etwas anderes? Ohne mehr Kontext ist es schwer zu wissen.

Anstatt

Freie Funktionen sind weniger verbreitet, aber sinnvoll, wenn eine Operation nicht eng mit einem bestimmten Typ oder einer bestimmten Instanz verknüpft ist.

Wie wäre es damit?

Freie Funktionen, die keiner Klasse oder einem Typ zugeordnet sind, sollten sparsam verwendet werden. Verwenden Sie nach Möglichkeit lieber eine Methode als eine freie Funktion. Dies trägt zur Lesbarkeit und Auffindbarkeit bei.

Kostenlose Funktionen sind am besten geeignet, wenn sie keinem bestimmten Typ oder einer bestimmten Instanz zugeordnet sind.

Ich öffne dieses Thema erneut, um weitere Diskussionen zu Free Function Exceptions zu suchen.

Nun, dies ist eine Standardbibliotheksfunktion. Es hat Vorrang in Sprachen wie R, Python, C#, C++. (über Boost).

Nun, dies ist eine Standardbibliotheksfunktion.

Wirklich? Ich habe es nicht in iOS verwendet ... * peinlich *

Ich werde es mir ansehen ... Wenn es unter iOS weit verbreitet ist / verwendet wird, ist meine Sorge hier vielleicht fehl am Platz ...

Ich mag Ihren Wortschatzvorschlag ... Ich möchte das Zip-Beispiel nur ungern aufgeben. (PS: Das RW Swift Team hat eine Charta, die größer (oder kleiner) als iOS ist.)

Das RW Swift Team hat eine Charta, die größer (oder kleiner) als iOS ist.

👍 Stimmt. ;]

Nachdem ich überprüft habe, was zip tut ,

Entschuldigung für meine Swift-Newbie-Moment-Erfahrung hier. 😉

Keine Bange. Danke für deine Hilfe wie immer. Übrigens, mir ist gerade aufgefallen, dass Sie in den Credits nicht erwähnt werden. Ich werde das auch reparieren.

Ich bin mir nicht sicher, ob kostenlose Funktionen jemals die beste Lösung sind. Wenn sie verwendet werden, sollten sie meiner Meinung nach Funktionen hinzufügen, die an anderer Stelle nicht behandelt werden.

max

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

maxElement sollte eine Eigenschaft und keine Methode sein, aber ich denke immer noch, dass die freie Funktion überflüssig ist. Wenn diese nicht dasselbe kompilieren, sollte der Compiler meiner Meinung nach verbessert werden, aber selbst wenn nicht, wird die Leistung meiner Meinung nach nie eine Rolle spielen; Ich glaube nicht, dass die Leute die max-Funktion mit vielen Elementen verwenden würden.

Postleitzahl
In C# wird zip als Äquivalent einer Swift-Protokollerweiterungsmethode implementiert . Ich denke nicht, dass das besser ist, aber es ist ein Beispiel dafür, wie man zip anders handhaben kann.

In Swift ist zip dasselbe wie dieser Initialisierer für Zip2Sequence . Es wäre schön, eine Möglichkeit zu haben, eine gezippte Sequenz einer variablen Anzahl von Eingabesequenzen darzustellen, aber bis dies geschieht, denke ich, dass die direkte Verwendung des Initialisierers in Ordnung ist.

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

Betreiber
Die überwiegende Mehrheit der kostenlosen Funktionen, die ich in Swift geschrieben habe, sind Operatoren. Ich habe gesehen, wie Chris Lattner und Joe Groff vorgeschlagen haben, Operatoren in Zukunft innerhalb von Typen à la C# zu definieren, sodass Operatoren auch für andere Funktionen den gewählten Konventionen folgen können. Ihre derzeitige Implementierung als Free-Function-only sollte wahrscheinlich nicht als Richtlinie verwendet werden.

Betreiber
Die überwiegende Mehrheit der kostenlosen Funktionen, die ich in Swift geschrieben habe, sind Operatoren. Ich habe gesehen, wie Chris Lattner und Joe Groff vorgeschlagen haben, dass Operatoren in Zukunft innerhalb von Typen à la C# definiert werden können...

Ja, das ist wahrscheinlich die Richtung, in die sich Swift in Zukunft bewegen wird. Hier ist ein relativ neuer Vorschlag von Chris Lattner, wie Sie bereits erwähnt haben.

Dies ist besonders bei Protokollen wie Equatable sonderbar, die gemäß unseren Richtlinien für Erweiterungen im Wesentlichen _erfordern_, dass Sie eine leere Erweiterung erstellen. Das ist bestenfalls umständlich. 😞

Ich stimme definitiv zu, dass Operatoren nicht als Beispiel für ideale kostenlose Funktionen verwendet werden sollten.

Danke für die Kommentare @Jessy- !

Einige Notizen:

Ich denke, dass maxElement() als Methode deklariert ist, weil es nicht O(1) ist, was für einige Benutzer überraschend sein könnte. Wenn Sie eine Eigenschaft implementieren, die nicht O(1) ist, muss sie klar dokumentiert werden. (In RW-Tutorials haben wir den Luxus, dass der gesamte Code offen liegt, sodass wir uns nicht so viele Sorgen machen oder ihn als Stilrichtlinie durchsetzen müssen.)

Auf der anderen Seite sind einige Formen von max<T: Comparable> O(1) und können spezialisiert werden, um die Vorteile von Hardware zu nutzen. (Ich vermute, deshalb gibt es zusätzlich zur Variadic-Version eine Zwei-Parameter-Version, obwohl ich das nicht bestätigt habe.)

Ich denke, wir sind uns auf jeden Fall einig, dass mit kostenlosen Funktionen sparsam umgegangen werden sollte, aber ich würde _niemals_ zurückweisen. Die verwendeten Beispiele stammen aus der Standardbibliothek. Ich habe keine Vorschläge gesehen, die Funktion zip aus der Standardbibliothek zu entfernen. Gibt es Einwände gegen die Besonderheiten der @JRG-Developer-Umformulierung oder den derzeit zusammengeführten Pull-Request modulo dieser Umformulierung?

Fühlen Sie sich frei, wieder zu öffnen, wenn Sie der Meinung sind, dass es noch etwas gibt, das besprochen werden muss. (Mit dem Update-Zweig zusammengeführt.)

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen

Verwandte Themen

designatednerd picture designatednerd  ·  22Kommentare

agirault picture agirault  ·  3Kommentare

samkim102 picture samkim102  ·  4Kommentare

sima-11 picture sima-11  ·  5Kommentare

WingYn picture WingYn  ·  15Kommentare