MySQL Java JavaScript PHP Python HTML-CSS C-sharp C++ Go

Funcții și parametrii lor

O funcție reprezintă un bloc de instrucțiuni care, împreună, realizează o anumită sarcină. Cu ajutorul funcțiilor, putem apela de mai multe ori acest bloc de instrucțiuni ca un întreg în diferite părți ale programului.

O funcție se declară astfel:

func nume_funcție (listă_parametri) (tipuri_valori_returnate) {
    instrucțiuni_de_executat
}

Funcția este definită folosind cuvântul cheie func, urmat de numele funcției. Apoi, între paranteze, se află lista de parametri. După lista de parametri, se definesc tipurile valorilor returnate de funcție (dacă funcția returnează valori). După aceea, între acolade se află instrucțiunile care formează funcția.

Numele funcției, împreună cu tipurile parametrilor săi și tipurile valorilor returnate, este cunoscut și sub denumirea de semnătură a funcției.

Implicit, fiecare program Go trebuie să conțină cel puțin o funcție – funcția main, care reprezintă punctul de intrare în aplicație:

package main
import "fmt"

func main() {
    fmt.Println("Hello Go")
}

Funcția main începe cu cuvântul cheie func, urmat de numele main. Funcția nu acceptă parametri, așa că după nume urmează paranteze goale. Funcția main nu returnează niciun rezultat, astfel că după parantezele goale nu se specifică tipul valorii returnate. Corpul funcției, între acolade, constă în apelul unei alte funcții – fmt.Println(), care afișează un șir pe consolă.

Acum să definim o altă funcție:

package main
import "fmt"

func main() {

}

func hello() {
    fmt.Println("Hello World")
}

În acest caz, am definit funcția hello, care nu acceptă parametri, nu returnează nimic și pur și simplu afișează un șir pe consolă. O funcție poate fi definită în același fișier în care se află funcția main. Totuși, dacă rulăm acest program, nu vom vedea nimic pe consolă, deoarece programul execută doar acțiunile definite în cadrul funcției main. Funcția main este punctul de intrare în aplicație. Dacă dorim să executăm funcția noastră hello, trebuie să o apelăm în cadrul funcției main:

package main
import "fmt"

func main() {
    hello()
    hello()
    hello()
}

func hello() {
    fmt.Println("Hello World")
}

Pentru a apela o funcție, scriem numele acesteia, urmat de paranteze în care se indică valorile pentru parametrii funcției. Deoarece funcția hello nu are parametri, vom scrie doar paranteze goale. Astfel, când programul este executat, șirul "Hello World" va fi afișat de trei ori pe consolă:

Hello World
Hello World
Hello World

Astfel, definirea unui grup de instrucțiuni sub forma unei funcții ne permite să nu scriem de fiecare dată întregul grup de instrucțiuni, ci să facem referire la el prin numele funcției.

Parametrii funcției

Prin parametri, o funcție primește date de intrare. Parametrii sunt specificați între paranteze, după numele funcției. Pentru fiecare parametru, se indică numele și tipul acestuia (ca la o variabilă). Parametrii sunt separați prin virgule. La apelarea funcției, trebuie să transmitem valori pentru toți parametrii acesteia. De exemplu, să presupunem că dorim să folosim o funcție care adună două numere:

package main
import "fmt"

func main() {
    add(4, 5)   // x + y = 9
    add(20, 6)  // x + y = 26
}

func add(x int, y int) {
    var z = x + y
    fmt.Println("x + y = ", z)
}

Funcția add are doi parametri: x și y. Ambii parametri sunt de tipul int, adică numere întregi. În cadrul funcției, se definește o variabilă care stochează suma acestor numere. Apoi, suma numerelor este afișată pe consolă.

În funcția main este apelată funcția add. Deoarece funcția primește doi parametri, trebuie să-i transmitem acestei funcții două argumente, iar valorile transmise trebuie să corespundă tipului parametrilor. Adică, dacă un parametru este de tipul int, trebuie să-i transmitem un număr.

Valorile sunt transmise în funcție de poziție. Adică, primul parametru va primi primul argument, al doilea parametru va primi al doilea argument și așa mai departe. În rezultat, vom obține următorul output pe consolă:

x + y = 9
x + y = 26

Dacă mai mulți parametri succesivi au același tip, putem să indicăm tipul doar pentru ultimul parametru, iar ceilalți parametri vor avea același tip:

package main
import "fmt"
 
func main() {
    add(1, 2, 3.4, 5.6, 1.2)
}
func add(x, y int, a, b, c float32){
    var z = x + y
    var d = a + b + c
    fmt.Println("x + y = ", z)
    fmt.Println("a + b + c = ", d)
}

La apelarea funcției, ca argumente, pot fi transmise și valori de variabile, rezultate ale operațiunilor sau ale altor funcții, dar trebuie avut în vedere că argumentele sunt întotdeauna transmise prin valoare:

package main
import "fmt"
 
func main() {
    var a = 8
    fmt.Println("a before: ", a)
    increment(a)
    fmt.Println("a after: ", a)
}
func increment(x int){
 
    fmt.Println("x before: ", x)
    x = x + 20
    fmt.Println("x after: ", x)
}

Ieșirea pe consolă:

a before: 8
x before: 8
x after: 28
a after: 8

În acest caz, ca argument pentru funcția increment, se transmite valoarea variabilei a. Parametrul x primește această valoare și aceasta este crescută cu 20. Cu toate acestea, chiar dacă valoarea parametrului x a fost mărită, valoarea variabilei a nu s-a schimbat. Acest lucru se întâmplă pentru că, la apelarea funcției, se transmite o copie a valorii variabilei.

Număr nelimitat de parametri

În Go, o funcție poate accepta un număr nelimitat de parametri de același tip. De exemplu, să presupunem că trebuie să obținem suma unor numere, dar nu știm exact câte numere vor fi transmise funcției:

package main
import "fmt"
 
func main() {
    add(1, 2, 3)        // sum = 6
    add(1, 2, 3, 4)     // sum = 10
    add(5, 6, 7, 2, 3)  // sum = 23
}
 
func add(numbers ...int){
    var sum = 0
    for _, number := range numbers{
        sum += number
    }
    fmt.Println("sum = ", sum)
}

Pentru a defini un parametru care acceptă un număr nelimitat de valori, punem trei puncte înainte de tipul acestora: numbers ...int. Astfel, prin acest tip de parametru, obținem mai multe valori de tip int.

La apelarea funcției, putem transmite un număr variabil de numere:

add(1, 2, 3)        // sum = 6
add(1, 2, 3, 4)     // sum = 10
add(5, 6, 7, 2, 3)  // sum = 23

Acesta trebuie să fie diferențiat de transmiterea unui slice ca parametru:

add([]int{1, 2, 3})
add([]int{1, 2, 3, 4})
add([]int{5, 6, 7, 2, 3})

În acest caz, vom obține o eroare, deoarece transmiterea unui slice nu este echivalentă cu transmiterea unui număr nelimitat de parametri de același tip. Dacă dorim să transmitem un slice, trebuie să indicăm trei puncte după argumentul array-ului:

add([]int{1, 2, 3}...)
 
add([]int{1, 2, 3, 4}...)
 
var nums = []int{5, 6, 7, 2, 3}
add(nums...)