strings.Builder
var sb strings.Builder
sb.WriteString("qwerty\n")
sb.WriteString("ytrewq")
fmt.Println(sb.String())
С помощью интерфейсов можно определить набор методов, которые должны быть реализованы различными типами. Интерфейсы обеспечивают абстракцию данных.
Mutex - позволяет только одной горутине писать/читать. RWMutex же позволяет нескольким горутинам читать и только одной писать.
Небуферизированный канал при записи блокируется, пока даные не будут прочтены и наоборот. Запись/чтение в буферизированный канал блокируется, только если буфер заполнен.
0 байт, тк struct{}{} не имеет полей.
Нет.
Пример:
m[0]=1
m[1]=124
m[2]=281
go не гарантирует порядок элементов в map, поэтому в случайном:
func main() {
nums := map[int]int{
0: 1,
1: 124,
2: 286,
}
for k := range nums {
fmt.Println(k)
}
}
[Running] go run "/Users/m/_go/wb_L1/main.go"
0
1
2
[Done] exited with code=0 in 0.259 seconds
[Running] go run "/Users/m/_go/wb_L1/main.go"
1
2
0
[Done] exited with code=0 in 0.232 seconds
make используется для создания и инициализации срезов, мап и каналов, возвращает обьект.
new возвращает указатель на нулевой обьект.
slice
// инициализация с использованием литерала
nums := []int{}
// make
nums := make([]int, 5, 10)
// var
var nums []int
map
// инициализация с использованием литерала
nums := map[int]int{}
// make
nums := make(map[int]int)
//создание nil map
var nums map[int]int
// создание указателя на nil map
nums := new(map[int]int)
func update(p *int) {
b := 2
p = &b
}
func main() {
var (
a = 1
p = &a
)
fmt.Println(*p)
update(p)
fmt.Println(*p)
}
1 1
В update передается указатель, его значение меняется локально и указывает на адрес b. Что бы увидеть изменение значения указателя, то нужно исправить код так: *p = b
func main() {
wg := sync.WaitGroup{}
for i := 0; i < 5; i++ {
wg.Add(1)
go func(wg sync.WaitGroup, i int) {
fmt.Println(i)
wg.Done()
}(wg, i)
}
wg.Wait()
fmt.Println("exit")
}
Выведется deadlock, тк в горутину передается копия wg, а значит, wg.Done() вызывается для копии. Нужно было передавать указатель на wg или использовать локальное значение для main(не передавать wg).
func main() {
n := 0
if true {
n := 1
n++
}
fmt.Println(n)
}
Выведет 0, тк в области видимости if создается новая переменная, которая не относится к области видимости main, а следовательно n в main не меняется. Чтобы у n изменилось значение, нужно было в условии использовать =, а не :=.
func someAction(v []int8, b int8) {
v[0] = 100
v = append(v, b)
}
func main() {
var a = []int8{1, 2, 3, 4, 5}
someAction(a, 6)
fmt.Println(a)
}
[100 2 3 4 5]
Срезы в го передаются по указателю, поэтому v[0] = 100 изменит a, append создает новый срез, который присваивается локальной переменной v.
func main() {
slice := []string{"a", "a"}
func(slice []string) {
slice = append(slice, "a")
slice[0] = "b"
slice[1] = "b"
fmt.Print(slice)
}(slice)
fmt.Print(slice)
}
[b b a][a a]
В функции создается новый срез, который не влияет на slice в main