Функции и указатели

08.10.2013

Но преди това...

Въпрос за мъфин #1

В кои случаи дадена променлива е достъпна извън пакета, в който е дефинирана?

Въпрос за мъфин #2

Кога обединяваме дефиницията на няколко променливи така

var (
    name string = "Мъфинчо"
    age uint8 = 5
)

вместо така

var name string = "Мъфинчо"
var age uint8 = 5

?

Въпрос за мъфин #3

Къде НЕ можем да ползваме type-inference?

Въпрос за мъфин #4

От какви типове може да бъде всяка константа?

Въпрос за мъфин #5

За какво се ползва ключовата дума iota?

Funcs 101

func се използва за три неща в езика

1. Функции
2. Ламбди
3. Методи

Подаване на аргументи

func fоо(a int, b string) float

Функцията foo приема int и string и връща float

Подаване на много аргументи

func sum(args ...int) int

Функцията sum приема произволен брой числа и връща техния сбор

func sum(args ...int) int {
    result := 0
    for _, v := range args {
        result += v
    }

    return result
}

Резултат от множество стойности

* Как е реализирано в "стари" езици:
- C/C++ и компания: масив или структура
- Python: tuple-и

* Как е реализирано в Go?
- Много просто: връщате каквото ви трябва

* Защо?
- По-лесно log-ване на грешки
- Улеснява handle-ване на състояния

package main

import "fmt"

func main() {
	fmt.Println(sumAndCount(2, 3, 4, 5))
}

func sumAndCount(args ...int) (int, int) {
    result := 0
    for _, v := range args {
        result += v
    }

    return result, len(args)
}

Ами ако не ни трябват всичките?

1. Знаем, че ако дефинираме променлива и не я използваме, гърми
2. Ако искаме онзи сбор и не ни интересува броят аргументи, това ще изгърми

result, count := sumAndCount(2, 3, 4, 5)

3. Ако нямаме нужда от дадена стойност, я присвояваме на _:

result, _ := sumAndCount(2, 3, 4, 5)

Именовани резултати

package main

import "fmt"

func main() {
	fmt.Println(sumAndCount(2, 3, 4, 5))
}

func sumAndCount(args ...int) (result int, count int) {
    count = len(args)
    result = 0
    for _, v := range args {
        result += v
    }

    return
}

Fun facts

...или да изпълни себе си

package main

import "fmt"

func main() {
	fmt.Println(factorial(5))
}

func factorial(x uint) uint {
    if x == 0 {
        return 1
    }

    return x * factorial(x-1)
}

Именоване на функции

Анонимни функции

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

package main

import "fmt"

func main() {
    add := func(x, y int) int { return x + y }
    fmt.Println(add(4, 5))

    fmt.Println(func(x, y int) int { return x + y }(3, 8))
}

Методи

За тях ще си говорим, като стигнем до дефиниране на типове

Указатели

Указатели

За останалите: Опреснителен курс

Пример

package main

import "fmt"

var (
    name   string = "Чочко"
    age    uint8  = 27
    p_name *string
)

func main() {
    p_name = &name
    fmt.Printf("name е на адрес %p и има стойност %s\n", p_name, name)
    fmt.Printf("age е на адрес %p и има стойност %d\n", &age, age)
}

Как да си направим дупка в крака?

package main

func main() {
    var p *int = nil
    *p = 0
}

Указатели и функции

func fоо(a int, b *string) float

Функцията foo приема int и указател към string и връща float

Демек a бива копиран в скоупа на foo, а b просто сочи към някаква стойност отвън.

Въпроси?