Skip to content

Commit 6c5c7d1

Browse files
authored
Merge pull request #69 from tsingbx/struct
add doc for struct
2 parents c9459d4 + 6051daf commit 6c5c7d1

8 files changed

Lines changed: 201 additions & 1 deletion

File tree

119-Structs/struct-1.gop

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// Maps are a convenient way to store some kinds of data, but they have
2+
// limitations. They don’t define an API since there’s no way to constrain a map to
3+
// only allow certain keys. All of the values in a map must also be of the same type.
4+
// For these reasons, maps are not an ideal way to pass data from function to
5+
// function. When you have related data that you want to group together, you
6+
// should define a struct.
7+
//
8+
// A struct type is defined with the keyword type, the name of the struct type, the
9+
// keyword struct, and a pair of braces ({}). Within the braces, you list the
10+
// fields in the struct. Just like we put the variable name first and the variable type
11+
// second in a var declaration, we put the struct field name first and the struct field
12+
// type second.
13+
//
14+
// Also note that unlike map literals, there are no commas separating
15+
// the fields in a struct declaration. You can define a struct type inside or outside of
16+
// a function. A struct type that’s defined within a function can only be used within
17+
// the function. Technically, you can scope a struct definition to any block level.
18+
//
19+
// Once a struct type is declared, we can define variables of that type.
20+
21+
type person struct {
22+
name string
23+
age int
24+
pet string
25+
}
26+
27+
var fred person
28+
29+
println(fred)
30+
31+
// Here we are using a var declaration. Since no value is assigned to fred, it gets
32+
// the zero value for the person struct type. A zero value struct has every field set
33+
// to the field’s zero value.

119-Structs/struct-2.gop

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# There are two different styles for a non-empty struct literal.
2+
// A struct literal can be specified as a comma-separated list of values for the fields
3+
// inside of braces:
4+
5+
type person struct {
6+
name string
7+
age int
8+
pet string
9+
}
10+
11+
tsb := person{}
12+
println(tsb)
13+
14+
julia := person{
15+
"Julia",
16+
40,
17+
"cat",
18+
}
19+
println(julia)
20+
21+
// When using this struct literal format, a value for every field in the struct must be
22+
// specified, and the values are assigned to the fields in the order they were
23+
// declared in the struct definition.

119-Structs/struct-3.gop

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
//
2+
// The second struct literal style looks like the map literal style:
3+
4+
type person struct {
5+
name string
6+
age int
7+
pet string
8+
}
9+
10+
beth := person{
11+
age: 30,
12+
name: "Beth",
13+
}
14+
println(beth)
15+
16+
// You use the names of the fields in the struct to specify the values. When you use
17+
// this style, you can leave out keys and specify the fields in any order. Any field
18+
// not specified is set to its zero value. You cannot mix the two struct literal styles;
19+
// either all of the fields are specified with keys, or none of them are. For small
20+
// structs where all fields are always specified, the simpler struct literal style is
21+
// fine. In other cases, use the key names. It’s more verbose, but it makes clear
22+
// what value is being assigned to what field without having to reference the struct
23+
// definition. It’s also more maintainable. If you initialize a struct without using the
24+
// field names and a future version of the struct adds additional fields, your code
25+
// will no longer compile.

119-Structs/struct-4.gop

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
//
2+
// A field in a struct is accessed with dotted notation:
3+
4+
type person struct {
5+
name string
6+
age int
7+
pet string
8+
}
9+
10+
bob := person{
11+
age: 30,
12+
name: "Beth",
13+
}
14+
bob.name = "Bob"
15+
println(bob.name)
16+
17+
// Just like we use brackets for both reading and writing to a map, we use dotted
18+
// notation for reading and writing struct fields.

119-Structs/struct-5.gop

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# Anonymous Structs
2+
// You can also declare that a variable implements a struct type without first giving
3+
// the struct type a name. This is called an anonymous struct.
4+
5+
var person struct {
6+
name string
7+
age int
8+
pet string
9+
}
10+
11+
person.name = "bob"
12+
person.age = 50
13+
person.pet = "dog"
14+
println(person)
15+
16+
pet := struct {
17+
name string
18+
kind string
19+
}{
20+
name: "Fido",
21+
kind: "dog",
22+
}
23+
println(pet)
24+
25+
// In this example, the types of the variables person and pet are anonymous
26+
// structs. You assign (and read) fields in an anonymous struct just like you do for a
27+
// named struct type. Just like you can initialize an instance of a named struct with
28+
// a struct literal, you can do the same for an anonymous struct as well.
29+
// You might wonder when it’s useful to have a data type that’s only associated
30+
// with a single instance. There are two common situations where anonymous
31+
// structs are handy. The first is when you translate external data into a struct or a
32+
// struct into external data (like JSON or protocol buffers). This is called
33+
// marshaling and unmarshaling data.
34+
//
35+
// Writing tests is another place where anonymous structs pop up.

119-Structs/struct-6.gop

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# Comparing and Converting Structs
2+
// Whether or not a struct is comparable depends on the struct’s fields. Structs that
3+
// are entirely composed out of comparable types are comparable; those with slice
4+
// or map fields are not (as we will see in later chapters, function and channel fields
5+
// also prevent a struct from being comparable).
6+
//
7+
// Unlike Python or Ruby, there’s no magic method that can be overridden to
8+
// redefine equality and make == and != work for incomparable structs. You can,
9+
// of course, write your own function that you use to compare structs.
10+
//
11+
// Just like Go+ doesn’t allow comparisons between variables of different primitive
12+
// types, Go+ doesn’t allow comparisons between variables that represent structs of
13+
// different types. Go+ does allow you to perform a type conversion from one struct
14+
// type to another if the fields of both structs have the same names, order, and
15+
// types. Let’s see what this means. Given this struct:
16+
17+
type firstPerson struct {
18+
name string
19+
age int
20+
}
21+
22+
type secondPerson struct {
23+
name string
24+
age int
25+
}
26+
27+
type thirdPerson struct {
28+
age int
29+
name string
30+
}
31+
32+
first := firstPerson{name: "Bob", age: 22}
33+
second := secondPerson{name: "Joe", age: 23}
34+
third := thirdPerson{name: "Sars", age: 24}
35+
first = firstPerson(second)
36+
println first
37+
first = firstPerson(third)
38+
println first
39+
40+
// We can use a type conversion to convert an instance of secondPerson to
41+
// firstPerson, but we can’t convert an instance of thirdPerson to firstPerson, because the
42+
// fields are in a different order.
43+
// But we can’t use == to compare an instance of firstPerson and an instance of secondPerson or thirdPerson,
44+
// because they are different types.

119-Structs/struct-7.gop

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Anonymous structs add a small twist to this: if two struct variables are being
2+
// compared and at least one of them has a type that’s an anonymous struct, you
3+
// can compare them without a type conversion if the fields of both structs have the
4+
// same names, order, and types. You can also assign between named and
5+
// anonymous struct types if the fields of both structs have the same names, order,
6+
// and types.
7+
8+
type firstPerson struct {
9+
name string
10+
age int
11+
}
12+
13+
f := firstPerson{
14+
name: "Bob",
15+
age: 50,
16+
}
17+
var g struct {
18+
name string
19+
age int
20+
}
21+
22+
g = f
23+
println f == g

119-Structs/struct.gop

Lines changed: 0 additions & 1 deletion
This file was deleted.

0 commit comments

Comments
 (0)