forked from ArchitectingSoftware/CNSE-Class-Demo-Files
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathstructs.go
More file actions
137 lines (115 loc) · 4.2 KB
/
Copy pathstructs.go
File metadata and controls
137 lines (115 loc) · 4.2 KB
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
130
131
132
133
134
135
136
137
package main
import "fmt"
//In go structs are collections of fields. They are useful for grouping data
//together to form records. On the surface they seem very similar to structs in
//C but they can do a lot more. We will see how we can add "methods" to structs
//to make them more powerful. This can be used for object oriented programming in go
type person struct {
name string
age int
sayName func()
}
// You can create a new struct by using the name of the struct and then assigning the
// values of the fields. Note that the order of the fields does not matter, you can
// specify them in any order.
func createStructTest() {
//Note in this case, Go assumes that the order of the values provided matches the
//order of the fields in the struct. This is not a good practice, but its good to
//know
p1 := person{name: "Bob", age: 20}
sh := func() {
p1ref := &p1
fmt.Println(p1ref.name)
}
p1.sayName = sh
p1.sayName()
p1.name = "BoBo"
p1.sayName()
fmt.Println(p1)
//This is a bit better, we are explicitly specifying the field names, so the order
//of the fields does not matter
p2 := person{name: "Alice", age: 30, sayName: sh}
fmt.Println(p2)
//We can also create a struct with each value initialized to its zero value. Zero
//values in go are defaults. For example, the zero value for an int is 0, the zero
//value for a string is "", the zero value for a bool is false, etc.
p3 := person{}
//We can then access the fields of the struct using the dot operator
p3.name = "Fred"
p3.age = 40
fmt.Println(p3)
}
// You can also create a pointer to a struct.
// A couple of things to note here: In this example there is no real difference
// between this and the previous example. The only difference is that we are
// using the & operator to indicate that we want a struct pointer. Go allocates
// memory for the structure on your behalf and garbage collects when the structure
// is no longer used. This is different from C where you have to explicitly allocate
// and free memory for the structure.
func createStructPointerTest() {
//Note in this case, Go assumes that the order of the values provided matches the
//order of the fields in the struct. This is not a good practice, but its good to
//know
// p1 := &person{"Bob", 20}
// fmt.Println(p1)
//This is a bit better, we are explicitly specifying the field names, so the order
//of the fields does not matter
p2 := &person{name: "Alice", age: 30}
fmt.Println(p2)
//We can also create a struct with each value initialized to its zero value. Zero
//values in go are defaults. For example, the zero value for an int is 0, the zero
//value for a string is "", the zero value for a bool is false, etc.
p3 := &person{}
//We can then access the fields of the struct using the dot operator
p3.name = "Fred"
p3.age = 40
fmt.Println(p3)
}
func structAndPointerDemo() {
//In this case p1 is created on the stack and initialized
p1 := person{name: "Alice", age: 30}
fmt.Println(p1)
//In this case p2 is a copy of p1. So changing p2 does not change p1
p2 := p1
p2.name = "Bob"
p2.age = p1.age + 10
fmt.Println(p1)
fmt.Println(p2)
p3 := person{name: "Joe", age: 50}
fmt.Println(p3)
p4 := &p3
p4.name = "Fred"
p4.age = p3.age + 10
fmt.Println(p3)
fmt.Println(p4)
}
//Lets see how this can also be used with functions
// Go does not have official constructors this is the idiomatic way to create a new
// person struct. Notice the type is *person, this means that the function returns
// a pointer to a person struct.
func newPerson(name string) *person {
//You can safely return a pointer to a local variable as a local variable
//will survive the scope of the function
return &person{name: name}
}
func newPersonTest() {
p := newPerson("Jon")
fmt.Println(p)
}
func newPersonValueCopy(name string) person {
return person{name: name}
}
func newPersonValueCopyTest() {
//In this case the person is copied back, this could get inefficent for large structs
p := newPersonValueCopy("Jon")
fmt.Println(p)
}
func RunStructsDemo() {
fmt.Println("------ Running Structs Demo ------")
createStructTest()
createStructPointerTest()
structAndPointerDemo()
newPersonTest()
newPersonValueCopyTest()
fmt.Printf("-----------------------------------\n\n")
}