1 Funktionsgrundlagen
In der Programmierung ist eine Funktion ein Code-Stück, das eine spezifische Aufgabe erfüllt und Eingabeparameter sowie Rückgabewerte haben kann. In der Go-Sprache werden Funktionen weit verbreitet eingesetzt, um Code zu organisieren und wiederzuverwenden. Durch den effektiven Einsatz von Funktionen kann der Code prägnanter, gut lesbar und leicht wartbar gemacht werden.
Funktionen sind ein Kernbestandteil der Go-Sprache, und das Verständnis, wie man Funktionen deklariert und definiert, ist entscheidend für das Schreiben effizienten und gut lesbaren Codes.
2 Definition von Funktionen
2.1 Funktionsdeklaration
In der Go-Sprache hat die allgemeine Form der Funktionsdeklaration folgendes Format:
func Funktionsname(Parameter) Rückgabetyp {
// Funktionskörper
}
Diese Bestandteile lassen sich wie folgt erklären:
- Das Schlüsselwort
func
wird verwendet, um eine Funktion zu deklarieren. -
Funktionsname
ist der Name der Funktion, der den Benennungskonventionen der Go-Sprache folgt. Eine Funktion mit einem Großbuchstaben am Anfang ist exportierbar, was bedeutet, dass sie außerhalb des Pakets sichtbar ist. Eine Funktion mit einem Kleinbuchstaben am Anfang ist nicht exportierbar und kann nur im selben Paket verwendet werden. -
Parameter
ist die Liste der Parameter, die die Funktion erhält, durch Kommas getrennt. Der Typ jedes Parameters muss angegeben werden, und wenn mehrere Parameter den gleichen Typ haben, kann der Typ nur einmal angegeben werden. -
Rückgabetyp
ist der Typ des Rückgabewerts der Funktion. Wenn die Funktion keinen Wert zurückgibt, kann dieser Teil weggelassen werden. Wenn die Funktion mehrere Werte zurückgibt, müssen sie in Klammern eingeschlossen werden.
Zum Beispiel können wir eine einfache Funktion deklarieren, um die Summe von zwei ganzen Zahlen zu berechnen:
func Add(a int, b int) int {
return a + b
}
In diesem Beispiel ist der Funktionsname Add
, sie nimmt zwei Parameter vom Typ int
(a und b) an und gibt ihre Summe mit dem Rückgabetyp int
zurück.
2.2 Parameterliste
Die Parameterliste definiert, welche Parameter die Funktion akzeptiert und welchen Typ jeder Parameter hat. Parameter sind eine besondere Art von Variablen, die verwendet werden, um Daten an eine Funktion zu übergeben.
func Greet(name string, age int) {
fmt.Printf("Hallo, %s! Du bist %d Jahre alt.\n", name, age)
}
In dieser Greet
-Funktion sind name
und age
Parameter. Der Typ von name
ist string
und der Typ von age
ist int
. Beim Aufrufen dieser Funktion müssen tatsächliche Werte für diese Parameter bereitgestellt werden.
2.3 Rückgabetypen
Funktionen können berechnete Ergebnisse zurückgeben, und der Rückgabetyp definiert den Datentyp des Rückgabewerts der Funktion. Funktionen können keinen Rückgabewert haben, oder sie können einen oder mehrere Rückgabewerte haben.
Wenn eine Funktion mehrere Rückgabewerte hat, sollten ihre Typen bei der Deklaration in Klammern eingeschlossen werden:
func Divide(dividend, divisor float64) (float64, error) {
if divisor == 0 {
return 0, errors.New("kann nicht durch null teilen")
}
return dividend / divisor, nil
}
Die Divide
-Funktion gibt hier zwei Werte zurück: den Quotienten und eine Fehlermeldung. Wenn der Divisor null ist, wird ein Fehler zurückgegeben.
2.4 Variadische Parameter
In Golang, wenn wir nicht sicher sind, wie viele Parameter der Aufrufer beim Definieren einer Funktion übergeben wird, können wir variadische Parameter verwenden. Variadische Parameter werden durch eine Ellipse ...
gekennzeichnet, was bedeutet, dass die Funktion eine beliebige Anzahl von Parametern akzeptieren kann. Dies ist sehr nützlich, wenn es um eine ungewisse Menge an Daten oder die Implementierung bestimmter Arten von Funktionen wie Formatierung, Zusammenfassung oder Iterationsfunktionen geht.
Anwendungsszenarien
Variadische Parameter werden häufig in den folgenden Szenarien verwendet:
-
Zeichenkettenverkettung: wie die Funktionen
fmt.Sprintf
undstrings.Join
. - Array/Slice-Verarbeitung: beim Umgang mit Arrays oder Slices variabler Länge, wie bei der Berechnung der Summe oder der Verkettung mehrerer Slices.
-
Protokollierung und Fehlerbehandlung: beim Umgang mit mehreren Fehlern oder der Aufzeichnung mehrerer Protokollinformationen, wie
log.Printf
oder benutzerdefinierten Fehlerzusammenfassungsfunktionen. - Hilfsfunktionen: die in APIs oder Bibliotheken verwendet werden, um Benutzern flexiblere Möglichkeiten zur Aufruf von Funktionen bereitzustellen.
Verwendung von variablen Parametern
Hier ist ein einfaches Beispiel zur Verwendung von variablen Parametern:
// Definiere eine Funktion, die eine variable Anzahl von ganzzahligen Parametern entgegennimmt und ihre Summe zurückgibt
func Summe(nums ...int) int {
total := 0
for _, num := range nums {
total += num
}
return total
}
func main() {
// Du kannst eine beliebige Anzahl von Parametern übergeben
fmt.Println(Summe(1, 2)) // Ausgabe: 3
fmt.Println(Summe(1, 2, 3, 4)) // Ausgabe: 10
// Du kannst auch ein Slice übergeben und nach dem Slice die Ellipse verwenden
zahlen := []int{1, 2, 3, 4, 5}
fmt.Println(Summe(zahlen...)) // Ausgabe: 15
}
In der Summe
-Funktion ist nums
ein Slice von Ganzzahlen, der alle Parameter enthält, die an die Summe
-Funktion übergeben werden. Wir können eine Range-Schleife verwenden, um durch diesen Slice zu iterieren und die Summe zu berechnen.
Es ist erwähnenswert, dass variable Parameter innerhalb der Funktion tatsächlich ein Slice sind, sodass alle mit Slices verbundenen Operationen verwendet werden können. Wenn du einen Slice als variablen Parameter an eine Funktion übergeben möchtest, füge einfach nach dem Slice eine Ellipse ...
hinzu.
Die Verwendung von variablen Parametern kann Funktionsaufrufe flexibler und prägnanter machen, hat jedoch auch einen leichten Einfluss auf die Leistung, da die Verwendung von variablen Parametern die Erstellung von Slices und die Speicherzuweisung beinhaltet. Daher sollte Vorsicht geboten sein, wenn strenge Leistungsanforderungen bestehen.
Tipp: Detaillierte Erklärungen zu Slices werden in späteren Kapiteln bereitgestellt. Wenn du Erfahrung mit anderen Programmiersprachen hast, kannst du sie vorübergehend als Arrays betrachten.
3 Funktionsaufrufe
3.1 Grundlegende Funktionsaufrufe
Das Aufrufen einer Funktion bedeutet das Ausführen des Funktionscodes. In Go ist das Aufrufen einer definierten Funktion sehr einfach, verwende einfach den Funktionsnamen und übergebe die entsprechenden Parameter. Zum Beispiel:
ergebnis := add(3, 4)
fmt.Println(ergebnis) // Ausgabe: 7
In diesem Beispiel wird die add
-Funktion aufgerufen und zwei Ganzzahlen als Parameter übergeben, und dann wird das zurückgegebene Ergebnis der Variablen ergebnis
zugewiesen.
3.2 Parameterübergabe
Beim Übergeben von Parametern an eine Funktion verwendet Go standardmäßig die Wertübergabe, was bedeutet, dass eine Kopie des Parameterwerts übergeben wird und die ursprünglichen Daten nicht geändert werden. Wenn du jedoch möchtest, dass die Funktion externe Variablen ändert oder aus Leistungsgründen, kannst du die Verweisübergabe verwenden, beispielsweise durch die Verwendung von Zeigern oder die Übertragung großer Strukturen.
Hier sind Beispiele für Wertübergabe und Verweisübergabe:
// Beispiel für Wertübergabe
func verdoppeln(wert int) {
wert *= 2
}
// Beispiel für Verweisübergabe
func verdoppelnZeiger(wert *int) {
*wert *= 2
}
func main() {
wert := 3
verdoppeln(wert)
fmt.Println(wert) // Gibt 3 aus, wert bleibt unverändert
verdoppelnZeiger(&wert)
fmt.Println(wert) // Gibt 6 aus, wert wurde verdoppelt
}
Im obigen Beispiel versucht die verdoppeln
-Funktion, den übergebenen wert
zu verdoppeln, verdoppelt jedoch nur ihre Kopie und lässt die ursprüngliche wert
-Variable unverändert. Die verdoppelnZeiger
-Funktion ändert jedoch den Wert der ursprünglichen Variable, indem sie einen Zeiger auf eine Ganzzahlvariable als Parameter empfängt.