ЧичковитеЧервенотиквеничета валидно име на функция ли е? Защо?
Защо 4chan не е валидно име на функция?
Ако foo е указател, то как се достъпва стойността към която сочи?
*foo
Ако имате само указател към uint32, намиращо се в масив, как ще достъпите следващото число в масива?
Имайки реда `bar, _ = foo()`, как се достъпва стойноста в _?
_ прилича само външно на $_ в perl/dev/null
note: Не сме секта.
package main
import "fmt"
func main() { var x [5]float64 x[0] = 98 x[1] = 93 x[2] = 77 x[3] = 82 x[4] = 83 var total float64 = 0 for i := 0; i < 5; i++ { total += x[i] } fmt.Println(total / 5) }
Очевидно броим от 0
var x [5]string x[0] = "Баба" x[1] = "меца" x[2] = "яде" x[3] = "от" x[4] = "медеца"
или накратко:
x := [6]float64{98, 93, 77, 82, 83}Чакай малко! Подали сме само 5 числа.
x[5] == 0
x := [...]string{"Incredible", "isn't", "it?"}x е от тип [3]stringДа разгледаме следния код
package main
import "fmt"
func main() {
dqdo := [4]uint32{0, 1, 2, 3} baba := [4]uint32{0, 1, 2, 3} fmt.Printf("The two arrays are identical: %t\n", dqdo == baba)
}
package main
import "fmt"
func main() {
dqdo := [4]uint32{0, 1, 2, 3} baba := [5]uint32{0, 1, 2, 3} fmt.Printf("The two arrays are identical: %t\n", dqdo == baba)
}
func (foo [100]uint32)
a := [100]float64 b := a
func (foo *[100]uint32)
len() - връща размера като intrange - ключова дума, която позволява да итерираме по индекс и стойностfor index, value := range arr {
...
}
for index := 0; index < len(arr); index++ {
value := arr[index]
...
}Тези два цикъла са еквивалентни
Като масивите имат дължина и могат да се индексират, но дължината им може да се променя.
var x []float64
Горното само създава променливата, а се инициализира по следния начин:
x := make([]float64, 5)
Това указва на слайса да бъде с размер 5. Всеки слайс е част от масив с не по-малка дължина от слайса.
x := make([]float64, 5, 10)
Това е същото като горното, но този слайс сочи към масив с размер 10.
numbers := []float64{0, 1.2, 3.4, 55.3}arr := [6]float64{1, 2, 3, 4, 5, 6}
x := arr[1:5]Създаваме слайс от втори до четвърти елемент включително на масива arr.
x := arr[2:] // Взема всички без първите два елемента x := arr[:2] // Взема първите два елемента x := arr[:] // Взема всички елементи
x := []int{2, 3, 5, 7, 11}Създава нов slice, който сочи към нов масив от 5 елемента.
y := x[1:3]
Създава нов slice, но не и нов масив - използва се вече съществуващия за x.
len(x) - Взема размера на slice-аcap(x) - Взема размера на масива, към който slice-а сочиpackage main
import "fmt"
func main() { x := []int{2, 3, 5, 7, 11} y := x[1:3] fmt.Println("len(x) =", len(x), ", cap(x) =", cap(x)) fmt.Println("len(y) =", len(y), ", cap(y) =", cap(y)) }
var foo []uint32 foo == nil // True
len и cap връщат 0 за нулев slicelen(foo) == cap(foo) == 0
x := []uint32{0, 1, 2, 3, 4, 5, 6, 7}
y := x[:]
y[4] = 42
x[4] == 42 // Truey не копира съдържанието на xxx := []uint32{0, 1, 2, 3, 4, 5, 6, 7}
y := x[2:4] // [2, 3]
y = y[:cap(y)] // [2, 3, 4, 5, 6, 7]Built-in функция, която добавя елементи към края на slice:
sliceA := []int{1, 2, 3}
sliceB := append(sliceA, 4, 5) // [1 2 3 4 5]Може да добавя и един slice към друг:
sliceC := append(sliceA, sliceB...)
Ако в резултатния slice има достатъчно място, той се използва непроменен. Ако няма, автоматично се заделя по-голям slice:
sliceD := make([]int, 0, 3) // len = 0, cap = 3 sliceD = append(sliceD, 1, 2) // len = 2, cap = 3 sliceD = append(sliceD, 2, 4) // len = 4, cap = 6
Изтриване на n-ия елемент от слайс
x := []int{1, 2, 3, 4, 5}
x = append(x[:n], x[n+1:]...)Ако n = 2:
[]int{1, 2, 4, 5}var l int
slice1 := []int{1, 2, 3, 4}
slice2 := []int{7, 6, 5}
Копираме трите елемента от slice2 в slice1
l = copy(slice1, slice2) // slice1 = [7 6 5 4], l = 3
Копираме края на slice1 в началото му
l = copy(slice1, slice1[2:]) // slice1 = [3 4 3 4], l = 2
Копираме slice1 в slice2
l = copy(slice2, slice1) // slice2 = [1 2 3], l = 3 // Копират се само първите 3 елемента, защото len(slice2) = 3
1. Опит за писане в неинициализиран слайс води до паника.
2. Масивите, в които се съхраняват данните на слайсовете, не се чистят от garbage collector-a, докато има референции (слайсове) към тях.
// WARNING: shitty code, don't do this
func GetFileHeader(filename string) []byte {
b, _ := ioutil.ReadFile(filename)
return b[:10]
}Цялото съдържание на файла няма да бъде изчистено от паметта, докато първите 10 байта се ползват някъде.
Решение: copy() в нов слайс
Неподредена колекция от двойки ключове и стойности
var x map[string]int // Ключовете в x са низове, а стойностите числа
За да го инициализраме, ползваме make:
x := make(map[string]int)
Подобно на слайсовете, писането в неинициализиран map води до паника.
Ползваме го почти както масиви и слайсове. Добавяне на стойност:
x["key"] = 10
За да вземем стойност по ключ:
value, ok := x["key"]
ok е true, ако съществува двойка с такъв ключ. В противен случай, value е нулевата стойност на типа ("" за string) и ok е false.
wordcount := map[string]int{"word1": 10, "word2": 5}delete:x := make(map[string]int) delete(x, "key") // Изтрива двойката с ключ е "key". Ако няма такава, нищо не се случва.
if _, ok := x["key"]; ok {
fmt.Println("key exists")
}range:for key, value := range m {
fmt.Println("Key:", key, "Value:", value)
}golang.org/ref/spec#Comparison_operators
type Person struct {
name string
age uint
}
var chochko Person
chochko.name = "Чочко"
chochko.age = 27Други начини за инициализиране:
chochko := Person{name: "Чочко", age: 27}
chochko := Person{"Чочко", 27}chochko := new(Person) chochko.name = "Чочко" chochko.age = 27
new само заделя и нулира памет, а make инициализира, т.е.:
package main import "fmt" type example struct { attrs map[string]int } func main() { e := new(example) e.attrs = make(map[string]int) e.attrs["h"] = 42 fmt.Println(e) }
make се ползва само върху slice и map