golang study notes --- struct supplement

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.

 

Guess you like

Origin www.cnblogs.com/saryli/p/12166555.html