Go / Олон утга буцаах

Олон утга буцаах

Go хэлний хамгийн гайхалтай онцлогуудын нэг бол функц нэгэн зэрэг хэд хэдэн утга буцааж чаддаг явдал юм. Python, JavaScript зэрэг хэлнүүдэд энэ боломж нэмэлт зохицуулалт шаарддаг. Харин Go-д энэ нь хэлний суурь хэсэг.

Энэ онцлог нь алдаа зохицуулах, хоёр утгыг нэгэн зэрэг буцаах зэрэг олон тохиолдолд маш хэрэгтэй.

Яагаад олон утга буцаах хэрэгтэй вэ?

Бодит амьдрал дээрх жишээг авч үзье. Тоог хуваах функц бичнэ гэж бодъё. Хуваагч нь тэг байвал алдаа гарна. Тэгэхээр функц нь хариу утгыг ч, алдааг ч хамт буцааж өгөх шаардлагатай.

Go-гүй орчинд үүнийг шийдэхэд хэд хэдэн арга байдаг — глобал алдааны хувьсагч, тусгай объект гэх мэт. Харин Go-д хамгийн энгийн шийдэл ажилладаг: хоёуланг нь буцаа.

Олон утга буцаах синтакс

Буцаах утгын төрлүүдийг хаалтанд жагсааж бичнэ:

go
package main

import "fmt"

// Хуваалт хийж, хариу болон алдааг хамт буцаана
func хувааx(a, b float64) (float64, string) {
    if b == 0 {
        return 0, "тэгд хуваах боломжгүй"
    }
    return a / b, ""
}

func main() {
    хариу, алдаа := хувааx(10, 2)
    if алдаа != "" {
        fmt.Println("Алдаа:", алдаа)
    } else {
        fmt.Println("Хариу:", хариу)
    }
}

Дэлгэцэнд дараах үр дүн гарна:

код
Хариу: 5

Функцийн (float64, string) хэсэг нь "хоёр утга буцаана — эхнийх нь float64, хоёр дахь нь string" гэсэн утгатай.

Алдааг буцаах Go-ийн хэв маяг

Go-д алдаа зохицуулах стандарт хэв маяг нь error төрлийг ашиглах юм. errors package-г оруулж ирнэ:

go
package main

import (
    "errors"
    "fmt"
)

func хувааx(a, b float64) (float64, error) {
    if b == 0 {
        return 0, errors.New("тэгд хуваах боломжгүй")
    }
    return a / b, nil
}

func main() {
    хариу, алдаа := хувааx(10, 0)
    if алдаа != nil {
        fmt.Println("Алдаа:", алдаа)
        return
    }
    fmt.Println("Хариу:", хариу)
}

Дэлгэцэнд:

код
Алдаа: тэгд хуваах боломжгүй

Энд хэд хэдэн шинэ зүйл байна:

  • error — Go-д суурилагдсан алдааны төрөл
  • errors.New(...) — шинэ алдааны утга үүсгэнэ
  • nil — утгагүй буюу "алдаа байхгүй" гэсэн утга. Go-д алдаа байхгүй үед nil буцаана

Утгыг орхих — _ ашиглах

Хэрэв буцаасан утгуудын заримыг ашиглахгүй бол _ (доогуур зураас) ашиглаж орхиж болно:

go
package main

import (
    "errors"
    "fmt"
)

func хувааx(a, b float64) (float64, error) {
    if b == 0 {
        return 0, errors.New("тэгд хуваах боломжгүй")
    }
    return a / b, nil
}

func main() {
    // Алдааг орхиж, зөвхөн хариуг авна (муу хэв маяг — зөвхөн жишээ болгон)
    хариу, _ := хувааx(10, 2)
    fmt.Println("Хариу:", хариу)
}

Гэхдээ алдааг _-ээр орхих нь ихэвчлэн муу хэв маяг байдаг. Бодит программд алдааг заавал шалгаарай.

Нэрлэсэн буцаах утга

Go-д буцаах утгуудад урьдчилан нэр өгч болно. Энэ нь кодыг илүү тодорхой болгодог:

go
package main

import "fmt"

// нийлбэр, дундаж гэж нэрлэсэн утгуудыг буцаана
func тооцоо(тоонууд []int) (нийлбэр int, дундаж float64) {
    for _, т := range тоонууд {
        нийлбэр += т
    }
    дундаж = float64(нийлбэр) / float64(len(тоонууд))
    return // return-д утга бичихгүй байж болно
}

func main() {
    н, д := тооцоо([]int{10, 20, 30})
    fmt.Println("Нийлбэр:", н)
    fmt.Println("Дундаж:", д)
}

Дэлгэцэнд:

код
Нийлбэр: 60
Дундаж: 20

return гэж бичихэд Go нь нэрлэсэн утгуудыг автоматаар буцаана. Үүнийг naked return гэж нэрлэдэг.

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

Variadic функцийг судална — нэг функцт хэдэн ч аргумент дамжуулж болдог тухай. Жишээлбэл, fmt.Println("a", "b", "c", "d") гэж дурын тооны утга дамжуулах боломж хэрхэн ажилладгийг ойлгоно.