/
description.ru.yml
130 lines (96 loc) · 3.56 KB
/
description.ru.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
---
name: Аргументы с указателем
theory: |
Указатели — очень обширная и непростая тема, выходящая за рамки данного курса. В этом уроке будут рассмотренны только основы передачи указателей на аргументы в функции:
```go
package main
import (
"fmt"
)
type User struct {
email string
password string
}
// при объявлении указываем,
// что переменная должна быть указателем.
// Для этого ставим звездочку * перед типом данных
func fillUserData(u *User, email string, pass string) {
u.email = email
u.password = pass
}
func main() {
u := User{}
// передаем указатель с помощью амперсанда
// & перед переменной
fillUserData(&u, "test@test.com", "qwerty")
fmt.Printf("points on func call %+v\n", u)
// points on func call {email:test@test.com password:qwerty}
// сразу инициализируем переменную с указателем
up := &User{}
fillUserData(up, "test@test.com", "qwerty")
fmt.Printf("points on init %+v\n", up)
// points on init {email:test@test.com password:qwerty}
}
```
Мапы по умолчанию передаются с указателем:
```go
package main
import (
"fmt"
)
func main() {
m := map[string]int{}
fillMap(m)
fmt.Println(m) // map[random:1]
}
func fillMap(m map[string]int) {
m["random"] = 1
}
```
Разработчики, пришедшие из других языков, часто используют фразы "передача по ссылке" или "ссылка на переменную". Строго говоря, в Go нет ссылок, только указатели:
```go
package main
import "fmt"
func main() {
a := 1
b := &a
c := &b
fmt.Printf("%p %p %p\n", &a, &b, &c)
// 0xc000018030 0xc00000e028 0xc00000e030
}
```
В этом примере *b* и *c* содержат одинаковые значения — адрес переменной *a*, однако *b* и *c* хранятся в разных адресах. Из-за этого обновление переменной *b* не изменит *c*. Поэтому если кто-то говорит про ссылки в Go, он имеет в виду указатели.
instructions: |
Реализуйте функцию `CopyParent(p *Parent) Parent`, которая создает копию структуры Parent и возвращает ее:
```go
type Parent struct {
Name string
Children []Child
}
type Child struct {
Name string
Age int
}
cp := CopyParent(nil) // Parent{}
p := &Parent{
Name: "Harry",
Children: []Child{
{
Name: "Andy",
Age: 18,
},
},
}
cp := CopyParent(p)
// при мутациях в копии "cp"
// изначальная структура "p" не изменяется
cp.Children[0] = Child{}
fmt.Println(p.Children) // [{Andy 18}]
```
tips:
- |
[The Go Programming Language Specification — Pointer types](https://golang.org/ref/spec#Pointer_types)
- |
[Указатели в Go](https://gobyexample.com/pointers)
- |
[Еще об указателях](https://www.digitalocean.com/community/conceptual-articles/understanding-pointers-in-go)