1. Definitions
Structure:
1, with the definition of complex data structures from
2, struct which may comprise a plurality of fields (attributes)
Distinction 3, struct types can be defined method, attention and functions
4, strucr type is a value type
5, struct type can be nested
6, go no language class type, only type struct
struct declaration:
type identifier struct { field1 type field2 type }
example:
type Student struct{ Name string Age int Score int }
struct three forms defined initialization three ways
a, was stu Student
b, was stu * Student = new (Student)
c、var stu *Student=&Student{}
Wherein pointers are pointing structure b and c of the return visit the following form:
a, stu.Name, stu.Age and stu.Score or (* stu) .Name, (* stu) .Age like
If it is in the form of a pointer can be accessed with the above conventional manner, in fact, automatically converted to the form of pointers to access
Complete example:
package main import ( "fmt" ) type Student struct{ Name string Age int score float32 } func main(){ // Declare a way was stu Student stu.Name="hua" stu.Age = 18 stu.score=80 // Declare Second way var stu1 *Student =&Student{ Age:20, Name:"hua", } // Declare Three ways was stu3 = Student { Age:20, Name:"hua", } fmt.Printf(stu1.Name) fmt.Printf(stu3.Name) }
Structure is a single user-defined type, and other types can not be cast
package main import ( "fmt" ) type integer int func main(){ // assign the type who does what, what we should cast to type was Integer = 1000 fmt.Println(i) where j = int 100 // where i is the self-defined types, j is of type int, so when the assignment to be cast, as follows j = int (i) // i if j is assigned to be cast to type int i = integer (j) // j to i if you want to copy must be converted into integer type fmt.Println(i) fmt.Println(j) }
Both Stu and Student above is an alias relationship, as though these two fields, but not the same type, because the type is defined
Factory Pattern
golang in the struct has no constructor, generally use the factory pattern to solve this problem
Package model
type student Struct{
Name string
Age int
}
func NewStudent(name string,age int)*Student{
return & Student {// create an instance of
Name:name
Age:age
}
}
Package main
S:new(student)
S:model.NewStudent(“tony”,20)
emphasize again
make to create the map, slice, channel
to create new value types
struct the tag
We can strct each field, consult a tag, the tag can be acquired by reflection, the most common scenario is json serialization and de-serialization
type student struct{
Name string "this is name field" // write a description of each field, as described in this field
Age int “this is age field”
}
json package
json.Marshal()
note:
json when packaged,
Field 1 capital, have to put in the structure before they can
The following is a statement packed program initiated in two ways
package main import( "encoding/json" "fmt" ) type Student struct{ Name string `json:"Student_name"` age int `json:"student_age"` score int `json:score` } func main(){ //statement was STU Student = Student { Name:"stu01", age:10, score:100, } data, err: = json.Marshal (stu) // packed, the return value byte if err!=nil{ fmt.Println("json encode stu faild,err",err) return } fmt.Println (string (data)) // byte is converted into the string } //{"Student_name":"stu01"} It can also be written in the following way package main import( "encoding/json" "fmt" ) type Student struct{ Name string `json:"Student_name"` age int `json:"student_age"` score int `json:score` } func main(){ //initialization was stu * Student = new (Student) stu.Name="stu01" data, err: = json.Marshal (stu) // packed, the return value byte if err!=nil{ fmt.Println("json encode stu faild,err",err) return } fmt.Println (string (data)) // byte is converted into the string } //{"Student_name":"stu01"}
Or example
package main import ( "encoding/json" "fmt" ) type Student struct { Name string `json:"Student_name"` Age int `json:"student_age"` score int `json:score` } func main() { //initialization was stu * Student = new (Student) stu.Name = "stu01" stu.Age = 20 stu.score = 90 data, err: = json.Marshal (stu) // packed, the return value byte if err != nil { fmt.Println("json encode stu faild,err", err) return } fmt.Println (string (data)) // byte is converted into the string } //{"Student_name":"stu01","student_age":20}
Anonymous field
Struct field can not name, called anonymous field
type Car struct{
Name string
Age int
}
type Train struct{
Car // anonymous field
Start time.Time // famous field
int // anonymous field
}
Anonymous field how to access it?
package main import ( "fmt" "time" ) type Cart struct { name string age int } type Train struct { Cart int strt time.Time } func main() { var t Train // formal written t.Cart.name = "001" t.Cart.age = 11 // above formal notation can be abbreviated to the following wording t.name = "001" t.age = 11 t.int = 200 fmt.Println(t) }
Anonymous conflict management field
type Cart struct { Name string Age int } type Train struct { Cart strt time.Time Age int }
For the above anonymous conflict, there is the principle of priority:
Abbreviations, if there are two structures have the same field, priority field itself, to find
type A struct { a int } type B struct { a int b int } type C struct { A B }
For the above anonymous conflict, you have to manually specify a field can, or will be error
2. The member variables
- Access control mechanisms
If the member variable name of a structure is capitalized, this variable is derived (ie, other packages can access).
A structure may include member variables can be derived and non-derived simultaneously
type A struct { Hour int // exportable minute int // can not be exported }
- limit
Type of naming structure S has not defined a member variable of the same structure type s, i.e. a type of polymerization can not contain its own. However, S can define a pointer type s, i.e., * S. as follows:
type S struct { value int // Next S // error Next * S // correct }
3. Compare the structure
- If all the member variable structure can compare, then the structure can be compared. Comparison of the two structures may be used or ==! =.
package main import "fmt" func main() { type C struct { A int B string } c1 := C{A: 1, B: "abc"} c2 := C{A: 1, B: "abc"} c3 := C{A: 2, B: "abc"} fmt.Println(c1.A == c2.A && c1.B == c2.B) //true fmt.Println (c1 == c2) // true with the equivalent fmt.Println(c1.A == c3.A && c1.B == c3.B) //false fmt.Println (c1 == c3) // false with the equivalent }
- And other types of comparison, like structures of a comparable type of map can be used as a key type.
package main import "fmt" func main() { type C struct { A int B string } mp := make(map[C]int) key := C{A: 1, B: "abc"} mp[key] = 9 fmt.Println(mp[C{A: 1, B: "abc"}]) //9 fmt.Println(mp)//map[{1 abc}:9] }
4. anonymous and nesting structure members
- go to allow the members of the body structure we define without a name, you only need to specify the type; the members of this structure known as an anonymous member. This type of structure member must be a name or type of pointer type pointing named. It is because of this structure nested functions, we can have direct access to the variables we need instead of specifying a long list of intermediate variables.
package main
import "fmt"
type Point struct {
X int
Y int
}
type Circle struct {
Point
}
type Wheel struct {
*Point
}
func main() {
var c Circle
cX = 10 // equivalent to c.Point.X = 10
cY = 10 // equivalent to c.Point.Y = 10
fmt.Println(c)
Wheel w
p := Point{1, 3}
w.Point = &p
fmt.Println(w.Point.X)
}
- Structure literal not initialized shortcut, you must follow the shape of the type definition.
import "fmt" type Point struct { X int Y int } type Circle struct { Point } func main() { var c Circle // c = Circle {1, 1} // Error c = Circle {Point {1, 1}} // correct c = Circle {Point: Point {1, 1}} // correct fmt.Println(c) }
-
Because the "anonymous member" has an implicit name, so you can not define two anonymous members of the same type in a structure which, otherwise it will lead to conflict. As the name Anonymous members is determined by their type, their exportability is also determined by their type. In the following example, these two anonymous Point and circle members is derived, even though the two structures is not derived (point and circle).
package main import "fmt" type point struct { X int Y int } type circle struct { point } type Wheel struct { circle } func main() { Wheel w wX = 8 // equivalent to w.circle.point.X = 8, wX is derived, w.circle.point.X is not derived fmt.Println(w) }
The method of structure
- Define
a similar statement and declaration of a normal function of the method, the knowledge in front of the function name added an extra parameter. The parameters of this method to bind to a type corresponding to this parameter.
Additional methods of parameter p becomes a recipient , which originated from the earlier object-oriented language, to describe the method of transmitting a message to the calling object.
package main import "fmt" type Point struct { X int Y int } func (p Point) print() { fmt.Println(p.X, p.Y) } func main() { var w = Point{1, 2} w.print() }
- The method defined limits: go and many other object-oriented languages, which can bind to a method except the pointer type and any type of interface types. Can be very convenient for the simple type (the plastic, string, slice, map, or even function, etc.) define additional behavior.
package main import "fmt" // Plastic type III int func (i III) print() { fmt.Println(i) } //function func Test() { fmt.Println("test") } type FunT func() func (f FunT) Print() { fmt.Println(f) } func main() { where f Funt f = Test f.Print() var i III = 3 i.print() }
- Method pointer recipient: Due to the calling function will copy each variable argument or if an argument is too big and we want to avoid copying the entire argument, so we have to use a pointer to pass the address of a variable. This also applies to the recipient update we bind it to the pointer type. When you call a method, the compiler will variables implicit conversion. To summarize the conditions structure method can be successfully invoked:
- Arguments recipient and the recipient is the same parameter types, such as are or are T * T. (5, 7)
- T receiver is the argument type variable and parameter * T is the receiver type, the compiler may implicit address acquisition variable (3).
- Argument is the recipient T type parameter T is the receiver type, the compiler will implicitly get the actual value. (2,6) One of the reasons is that 8 compilation error: Compiler for T type into an implicit conversion of type T, the recipient only argument is variable in order to succeed, because they can not obtain a temporary variable ground
package main import "fmt" type Point struct { X int Y int } func (p Point) Print() { fmt.Println(p.X, p.Y) } func (p *Point) ScaleBy(factor int) { p.X *= factor pY * = factor } func main() { p := Point{1, 1} ptr := &p p.Print () // 1. correct ptr.Print () // 2. correct p.ScaleBy (2) // 3. correct ptr.ScaleBy (2) // 4. correct Point {1, 1} .Print () // 5. Properly (& Point {1, 1}). Print () // 6. Properly (& Point {1, 1}). ScaleBy (2) // 7. Properly // Point {1, 1} .ScaleBy (2) // 8. Error }
- nil is a legitimate recipient: as some function allows nil pointer as an argument, the method allows the recipient pointer is nil
package main import "fmt" type A struct { Data int } func (a *A) FunPtrA() { fmt.Println("FunPtrA") } func main() { var ptrA *A ptrA = nil ptrA.FunPtrA() //FunPtrA }
- Structure composed by the embedded type: the main discussion here embedded structures and pointers to structures, access rights to the source definition of the structure function.