Go / Функц үндэс

Функц үндэс

Функц бол нэрлэгдсэн кодын блок — нэг удаа бичиж, хаанаас ч дуудаж ашиглаж болно. Програмыг функцуудад хуваах нь кодыг дахин ашиглах, тест хийх, уншихад хялбар болгодог. Энэ бол програмчлалын хамгийн чухал ойлголтуудын нэг.

Функц зарлах ба дуудах

go
package main

import "fmt"

// Функц зарлах
func greet() {
    fmt.Println("Сайн уу! Go-д тавтай морилно уу.")
}

func main() {
    greet()  // Функц дуудах
    greet()  // Хэдэн удаа ч дуудаж болно
    greet()
}

Гаралт:

код
Сайн уу! Go-д тавтай морилно уу.
Сайн уу! Go-д тавтай морилно уу.
Сайн уу! Go-д тавтай морилно уу.

Функц зарлах бүтэц: func [нэр]([параметрүүд]) [буцах төрөл] { ... }

greet() функц параметр ч авахгүй, утга ч буцаахгүй — зүгээр л ажиллуулдаг.

Параметртэй функц

Функцэд оролтын утга (параметр) дамжуулж болно:

go
package main

import "fmt"

func greetUser(name string) {
    fmt.Printf("Сайн уу, %s! Кодоо сурахад амжилт хүсье.\n", name)
}

func printLine(char string, count int) {
    for i := 0; i < count; i++ {
        fmt.Print(char)
    }
    fmt.Println()
}

func main() {
    greetUser("Болд")
    greetUser("Анар")
    greetUser("Сарнай")

    printLine("=", 30)
    printLine("-", 20)
    printLine("*", 10)
}

Гаралт:

код
Сайн уу, Болд! Кодоо сурахад амжилт хүсье.
Сайн уу, Анар! Кодоо сурахад амжилт хүсье.
Сайн уу, Сарнай! Кодоо сурахад амжилт хүсье.
==============================
--------------------
**********

Параметр нь name string хэлбэрт бичигдэнэ — эхлээд нэр, дараа нь төрөл. Хэд хэдэн параметр байвал таслалаар тусгаарлана.

Утга буцаах функц

return ашиглан функцээс утга буцаана:

go
package main

import "fmt"

func add(a int, b int) int {
    return a + b
}

func multiply(a, b int) int {  // ижил төрлийн параметрийг товчилж болно
    return a * b
}

func square(n float64) float64 {
    return n * n
}

func main() {
    result1 := add(10, 25)
    result2 := multiply(4, 7)
    result3 := square(5.5)

    fmt.Println("Нийлбэр:", result1)
    fmt.Println("Үржвэр:", result2)
    fmt.Printf("5.5-ийн квадрат: %.2f\n", result3)
}

Гаралт:

код
Нийлбэр: 35
Үржвэр: 28
5.5-ийн квадрат: 30.25

Буцах төрлийг параметрүүдийн хаалтны дараа бичнэ: func add(a int, b int) int. return хийсний дараах код ажиллахгүй тул return нь функцийн хамгийн сүүлд байна.

Функцийн хамрах хүрээ (scope)

Функц дотор зарласан хувьсагч нь зөвхөн тэр функцийн дотор хүчинтэй:

go
package main

import "fmt"

var globalCount int = 0  // бүх функцэд харагдана

func increment() {
    globalCount++
    localValue := 100  // зөвхөн энэ функцэд харагдана
    fmt.Println("Дотор утга:", localValue)
}

func main() {
    increment()
    increment()
    increment()

    fmt.Println("Глобал тоолуур:", globalCount)
    // fmt.Println(localValue)  // АЛДАА! localValue энд харагдахгүй
}

Гаралт:

код
Дотор утга: 100
Дотор утга: 100
Дотор утга: 100
Глобал тоолуур: 3

Глобал хувьсагчийг хэт их ашиглахаас зайлсхий — функцэд параметрээр дамжуулах нь кодыг тодорхой, тест хийхэд хялбар болгодог.

Функцийг параметр болгон дамжуулах

Go-д функц нь "first-class value" — функцийг бусад функцэд параметр болгон өгч болно:

go
package main

import "fmt"

func applyTwice(f func(int) int, x int) int {
    return f(f(x))
}

func double(n int) int {
    return n * 2
}

func addTen(n int) int {
    return n + 10
}

func main() {
    fmt.Println(applyTwice(double, 3))   // double(double(3)) = double(6) = 12
    fmt.Println(applyTwice(addTen, 5))   // addTen(addTen(5)) = addTen(15) = 25
}

Гаралт:

код
12
25

Функцийг параметр болгон дамжуулах нь дэвшилтэт хэв маяг (higher-order function) — дараагийн хичээлүүдэд улам их харна.

defer — хойшлуулах

defer нь функц дуусахад тухайн мөрийг ажиллуулна:

go
package main

import "fmt"

func main() {
    defer fmt.Println("3. Функц дуусав")  // хамгийн сүүлд ажиллана

    fmt.Println("1. Эхлэв")
    fmt.Println("2. Дундаа байна")
}

Гаралт:

код
1. Эхлэв
2. Дундаа байна
3. Функц дуусав

defer-ийг файл хаах, нөөцийг чөлөөлөх, цэвэрлэх үйлдэлд ашиглана. Файл нээсэн бол defer file.Close() гэж бичвэл яг хаах шаардлагатай үед автоматаар хаагдана.

Дараагийн хичээлд:

Go-ийн хамгийн хүчирхэг онцлогуудын нэг — нэг функцээс олон утга буцаах боломж. Алдааг зохицуулах (result, error) хэв маяг нь Go-ийн кодын суурь бүтэц бөгөөд дараагийн хичээлд нарийвчлан үзнэ.