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

20.10.2015

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

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

Коя е последната стабилна версия на Go?

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

Какъв трябва да е първия ред код в Go?

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

Какво му е специалното на пакета main?

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

Имате два пакета. Искате от единия да извикате функция в другия - какво е необходимо?

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

iota e коя подред буква в гръцката азбука?

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

Какво трябва да направите преди да качите домашно/предизвикателство?

Funcs 101

С func могат да се създават три неща

1. Функции

2. Ламбди

3. Методи

Аргументи

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

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

Когато няколко аргумента са от един тип

func bar(a, b int, c float64) float64

Произволен брой аргументи

func sum(args ...int) int

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

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

    return result
}

Извикваме я с колкото ни трябват

sum()           //0
sum(2, 3)       //5
sum(2, 3, 4, 5) //14

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

Множество стойности като резултат

package main

import "fmt"

func main() {
	fmt.Println("Резултатът от sumAndCount(2, 3, 4, 5) е")
	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)
}

Защо?

Как е реализирано в "стари" езици:

Как е реализирано в Go?

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

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

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

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

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

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

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

    return
}

Фунцкиите като стойности

func foo(bar func(int, float64) float64) float64 {
    return bar(5, 3.2)
}
func createRandomGenerator() func() int {
    return func() int {
        return 4
    }
}

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

package main

import "fmt"

func main() {
	fmt.Println("factorial(5) returns:")
	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
    pName *string
)

func main() {
    pName = &name
    fmt.Printf("name е на адрес %p и има стойност %s\n", pName, 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) float64

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

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

Домашно

Въпроси?