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

Tipul funcției

Fiecare funcție are un tip definit, care se formează din lista tipurilor parametrilor și lista tipurilor rezultatelor returnate. De exemplu, să luăm următoarea funcție:

func add(x int, y int) int{
    return x + y
}

Această funcție reprezintă tipul func(int, int) int. Același tip va corespunde și următoarei funcții:

func multiply(x int, y int) int{
    return x * y
}

Deși această funcție se numește diferit și efectuează alte acțiuni, ca tip al parametrilor și ca tip al rezultatului returnat, ea corespunde aceluiași tip de funcție menționat mai sus.

Să luăm încă o funcție:

func display(message string){
    fmt.Println(message)
}

Această funcție are tipul func(string). Adică, din nou, la început se află cuvântul func, urmat de tipurile parametrilor între paranteze. Deoarece funcția nu returnează niciun rezultat, tipul de returnare nu este specificat.

Dar ce înseamnă tipul funcției? Asta înseamnă că putem defini variabile sau parametri ai funcțiilor care vor reprezenta un anumit tip de funcție. Cu alte cuvinte, o variabilă poate fi o funcție. De exemplu:

package main
 
import "fmt"
 
func add(x int, y int) int{
    return x + y
}
 
func main() {
     
    var f func(int, int) int = add
    fmt.Println(f(3, 4))
     
    var x = f(4, 5)     // 9
    fmt.Println(x)
}

Aici, variabila f are tipul func(int, int) int, adică reprezintă orice funcție care primește doi parametri de tip int și returnează o valoare de tip int. Prin urmare, putem atribui acestei variabile funcția add, care corespunde acestui tip:

var f func(int, int) int = add

După aceasta, putem apela funcția atribuită prin variabilă, transmițând valorile necesare pentru parametrii săi:

var x = f(4, 5) // 9

De asemenea, variabila poate schimba funcția la care face referire, dar funcția trebuie să corespundă tipului său:

package main
 
import "fmt"
 
func add(x int, y int) int{ return x + y}
func multiply(x int, y int) int{ return x * y}
 
func display(message string){
    fmt.Println(message)
}
 
func main() {
     
    f := add        // sau așa: var f func(int, int) int = add
    fmt.Println(f(3, 4))        // 7
     
    f = multiply    // acum variabila f face referire la funcția multiply
    fmt.Println(f(3, 4))        // 12
     
    // f = display      // eroare, deoarece funcția display are tipul func(string)
     
    var f1 func(string) = display   // corect
    f1("hello")
}

Funcțiile ca parametri ai altor funcții

De asemenea, o funcție poate fi transmisă ca parametru într-o altă funcție. De exemplu:

package main
 
import "fmt"
 
func add(x int, y int) int {
    return x + y
}

func multiply(x int, y int) int {
    return x * y
}

func action(n1 int, n2 int, operation func(int, int) int){
    result := operation(n1, n2)
    fmt.Println(result)
}

func main() {
    action(10, 25, add)     // 35
    action(5, 6, multiply)  // 30
}

Aici, funcția action acceptă trei parametri. Primii doi parametri sunt numere, iar al treilea parametru este o funcție care corespunde tipului: func(int, int) int. Adică, al treilea parametru reprezintă o anumită acțiune și poate fi orice funcție care primește două valori de tip int și returnează, de asemenea, o valoare de tip int. Pentru exemplu, aici sunt definite două funcții similare care corespund acestui tip: add și multiply. Prin intermediul numelui parametrului operation, putem apela această funcție.

Sau un alt exemplu:

package main
 
import "fmt"
 
func isEven(n int) bool{
    return n % 2 == 0
}

func isPositive(n int) bool{
    return n > 0
}
 
func sum(numbers []int, criteria func(int) bool) int{
    result := 0
    for _, val := range numbers{
        if(criteria(val)){
            result += val
        }
    }
    return result
}

func main() {
    slice := []int{-2, 4, 3, -1, 7, -4, 23}
     
    sumOfEvens := sum(slice, isEven)    // suma numerelor pare
    fmt.Println(sumOfEvens)             // -2
     
    sumOfPositives := sum(slice, isPositive)    // suma numerelor pozitive
    fmt.Println(sumOfPositives)                 // 37
}
package main
 
import "fmt"
 
func isEven(n int) bool{
    return n % 2 == 0
}

func isPositive(n int) bool{
    return n > 0
}
 
func sum(numbers []int, criteria func(int) bool) int{
    result := 0
    for _, val := range numbers{
        if(criteria(val)){
            result += val
        }
    }
    return result
}

func main() {
    slice := []int{-2, 4, 3, -1, 7, -4, 23}
     
    sumOfEvens := sum(slice, isEven)    // suma numerelor pare
    fmt.Println(sumOfEvens)             // -2
     
    sumOfPositives := sum(slice, isPositive)    // suma numerelor pozitive
    fmt.Println(sumOfPositives)                 // 37
}

Aici, funcția sum calculează suma elementelor din slice, dar nu toate elementele, ci doar cele care îndeplinesc condiția. Condiția este transmisă sub forma unei funcții ca al doilea parametru. Condiția trebuie să corespundă tipului de funcție func(int) bool. Adică, funcția trebuie să primească ca parametru o valoare de tip int și să returneze o valoare de tip bool, care indică dacă numărul transmis respectă condiția.

Pentru exemplu, aici sunt definite două funcții ajutătoare: isEven (returnează true dacă numărul este par) și isPositive (returnează true dacă numărul este pozitiv). Aceste funcții corespund tipului func(int) bool, de aceea pot fi folosite ca și condiție.

Funcția ca rezultat al altei funcții

O funcție poate fi, de asemenea, returnată dintr-o altă funcție ca rezultat:

package main
 
import "fmt"
 
func add(x int, y int) int{ return x + y}
func subtract(x int, y int) int{ return x - y}
func multiply(x int, y int) int{ return x * y}
 
func selectFn(n int) (func(int, int) int){
    if n == 1 {
        return add
    } else if n == 2 {
        return subtract
    } else {
        return multiply
    }
}
 
func main() {
    f := selectFn(1)
    fmt.Println(f(3, 4))        // 7
     
    f = selectFn(3)
    fmt.Println(f(3, 4))        // 12
}

Aici, în funcție de valoarea parametrului, funcția selectFn returnează una dintre cele trei funcții: add, subtract sau multiply.