Go core development study notes (twenty) - structure sturct, method

Object-oriented programming (of OOP) : specific concepts do not speak, learned java, py are aware, there is no concept of golang class, the structure can be used to simulate alternative classes.
Golang support feature of object-oriented programming, OOP language removed traditional integration of method overloading, constructors and destructors, hidden this pointer or the like.

Structure:
extracting things the same features and acts to form a new data type is a structure, many instances can be created by a structure (similar to create multiple instances of the class is py);
the above description is made to solve the different attributes of a thing and have the method can not be uniformly defined in Golang, such as age, should not be to string type, but they require additional int to define an array or otherwise reserved, too boring.

Structure is defined:
★★★ value types, when the declaration of a structure type definition has been allocated memory, nothing is transmitted and waited in vain {0}
★★★ <of struct_name,> initials other programs may import the package , structure variable capitalized other programs can import this package to use this variable

type <struct_name>(nbaPlayers) struct {    // type,struct 关键字,结构体名字自己起,和python中的 Class <class_name> 同理
	Name string                                 
	Age int
	color string
	hobbie string
}

// After the completion of the above definitions, the lower structure can be used as a variable

var player1 nbaPlayers     //定义完了,nbaPlayers就是个结构体,和int,string等一样

Example:

package main
import "fmt"
func main() {
	type nbaPlayers struct {         
		Name string
		Age int
		color string
		hobbie string
	}
	
	//定义方式1:
	var player1 = nbaPlayers{"阿狗",23,"red","eatting"}
	fmt.Println(player1)                       // {阿狗 23 red eatting}
	
	//定义方式2: 使用 <实例>.<属性> 来读取相应的数值
	var player2 nbaPlayers        
	player2.Name = "阿猫"
	player2.Age = 20
	player2.color = "blue"
	player2.hobbie = "sleeping"
	fmt.Println(player2)                      // {阿猫 20 blue sleeping}
	
	//具体打印某个属性
	fmt.Println(player2.Age)                  // 20
	//具体还可以绑定nbaPlayers的方法(函数),后续再说
}

Field / property / Fields
because it is a value type, without values generated after example, the various types of data to default values :
Value Type:
BOOL: to false, String: "", 0 :: int, [n-] int: [n- a 0]
reference type:
zero value ptr, slice, map are nil, described no memory space is allocated, need the make () may be used after the
field structure different variables are independent from each, as is the type of value, one example of a change of the field does not affect the other instance.

package main
import "fmt"
func main() {
	type nbaPlayers struct {
		Name string
		Age int
		color string
		hobbie string
		Ptr *int
		Slice []int
		Map1 map[string]string
	}
	/*
	默认下面三种引用类型都是nil的,可以使用if ptr == nil 成立则输出结果来判断
	 */
	var temp = 2
	var player1 nbaPlayers
	player1.Ptr = &temp
	fmt.Println(player1.Ptr)
	if player1.Slice == nil {
		fmt.Println("OK")
	}
	player1.Slice = make([]int,2)   //
	player1.Slice[0] = 10
	player1.Slice[1] = 20

	for i := 0 ; i < 5 ; i++ {
		player1.Slice = append(player1.Slice, i)
	}
	fmt.Println(player1.Slice)
}

Four ways to structure assignment:

package main
import "fmt"
func main() {
	type Pl struct {
		Name   string
		Age    int
	}
	//方式1
	var p1 Pl = Pl{"dd",20,}
	fmt.Println(p1)
	//方式2
	var p2 Pl
	p2.Name = "ee"
	p2.Age = 20
	fmt.Println(p2)

	//方式3:返回结构体指针
	var p3 *Pl = new(Pl)
	p3.Name = "ff"         //设计者简化了写法,实际上p3都已经默认加了 (*p3)
	(*p3).Age = 20
	fmt.Println(*p3)

	//方式4:返回结构指针2
	var p4 *Pl = &Pl{}
	p4.Name = "gg"         //设计者简化了写法,实际上p4都已经默认加了 (*p3)
	(*p4).Age = 20
	fmt.Println(*p4)
}

Structure of the memory allocation mechanism

  1. Examples of two structures: p1, p2, p2 = p1, p2, modify the value will not affect p1, in line with the value of the copy, not described in detail here.
  2. If p2 is a pointer type structure, then p2 = & p1, p2 value of the field in the modified structure will affect p1, reference transmission line with previous, similar.
  3. All fields in the memory structure is continuously distributed, can be obtained corresponding to different values ​​of the address field of addition and subtraction.
  4. Nested structure, if the outer structure is a pointer type, then the address of the outer structure pointer must be continuous but the inner structure of the value of the point is not necessarily continuous, the computer needs to be calculated according to the actual situation.

Strong turn structure

  1. Can be converted, but the field is required and the type of structure to be identical to two, the number of types must match the name!
  2. Definition of a structure stuc1, var stuc2 stuc1, this is not being given, need stuc2 = Stu (stuc1), because then re type, stuc1 stuc2 not the same, and a data type same reason applied to any variable assignment:
var i integer = 10 
var j int = 20 
j = i      //也会报错!必须强转 j = int(i)这样才可以,虽然i也是int但是它是integer...

Structure and principles Details

  1. Go a language to write applications, client access, return to the Go language needs of client information, the general structure of the serialized json format (string) back to the server.
  2. Serialization need to import "encoding / json", see Note below code in the future development will encounter many `json:" <Field Name> ' `way.
  3. json.Marshal (<Examples>) will be frequently used.
    package main
    import (
    	"encoding/json"
    	"fmt"
    )
    type Nbaplayer struct {
    		Name string  `json:"name"`  //序列化需要引入import "encoding/json"
    		Num int      `json:"num"`   //由于json函数中使用结构体参数表示Nbaplayer要在别的包被使用,所以必须变量大写,不然返回空
    		Abil string  `json:"abil"`  //使用`json:"<字段名称>"` 这样后续json字符串首字母变小写了{"name":"durant","num":35,"abil":"四肢长"}
    }
    
    func main() {
    	var player1 = Nbaplayer{"durant",35,"四肢长"}     //实例化
    	jsonstring , _ := json.Marshal(player1)     //序列化函数 json.Marshal(),返回值是一个序列化结果和一个err,忽略err值取字符串
    	fmt.Println(jsonstring)                     //是一个字节类型的串儿,无法阅读[123 34 78 97 109 101 3...]
    	fmt.Println(string(jsonstring))             //如果想看懂用string()强转即可,{"Name":"durant","Num":35,"Abil":"四肢长"}
    	/*
    	json返回结构体字段注定都是变量大写,因为Golang规定大写才能被其他包使用,所以需要使用,`json:"<字段名称>"`这个就是tag方式
    	可以把首字母大写转成小写,这个里面用到了反射,后续再讲,现在还没学到。
    	 */
    }
    

method

  1. Reflected in the structure of things is just one example of the property, are declarative information, and can not complete the functional behavior, such as people eat and drink Lazard sleep behavior, can not be described by attributes.
  2. Similarly Python, class, attribute, which is a set of methods.
  3. Method Golang is acting on the specified data type, because the self class definition, can have a method, rather than struct, i.e. out of the type of data types can have methods.

The difference between the methods and functions:
sentence: In addition to a method other more binding (<arbitrary parameters> <Binding data type>) outside , using exactly the same way with other functions.
Similarly, it is the function FUNC <function name> (parameter) {...}, and since the method associated with the data type FUNC (<arbitrary parameters> <Binding data type>) <function name> (parameter) {...} difference is here.
Specific examples: type Cat struct {...}; func (maomao Cat) eat () {...} // type of a structure, the method can only be called by the latter type of data structure.
Random parameters is a parameter, somewhat similar to the python in the self.

See the code below:

package main
import "fmt"

type Persons struct {
	Name string
	Age int
}

func (p Persons) eat(<传参>) {                     //只能由某种数据类型的才可以调用的方法,其他实例不可以调用
	p.Name = "阿猫"
	fmt.Println("eat up lots of shit~",p.Name)      //调用方法的时候使用的是值拷贝,即副本拷贝,方法内部变量的改变并不会改变main函数中的实例的值
}

func main() {
	var p1 Persons = Persons{"阿狗",3}      //创建一个实例
	p1.eat()                               //实例使用一个方法,仅仅是Persons的生成的实例可以使用,调用函数所以输出阿猫
	fmt.Println(p1.Name)                   //最后p1.Name还是阿狗
}

Method calls and pass the principle of participation mechanisms

★★★★★ method calls and transfer mechanisms and function essentially the same parameters, is not the same as the method call, method call will be variable, as the argument to the method.

That is easy to understand the words, just behind the transmission (parameter) is, (p Person) will also pass a p, i.e. instance p; is the value of the variable value type is copied, the address is copied into a reference type.

Exercise: Creating properties and methods of seeking a circular area

package main

import "fmt"

type Circle struct {
	Radius float64
}

func (cir Circle) area(radius float64) float64 {
	pi := 3.141592653
	mianji := pi * radius * radius
	return mianji
}

func main() {
	var cir = Circle{10}
	area1 := cir.area(cir.Radius)     //这个cir是要传入func (cir Circle) area(radius float64) float64{}中的
	fmt.Println("圆形的面积为:",area1)
}

Methods and precautions discuss details

  1. Structure type is a value type, in the method call, the type of compliance value passed is the value of the copy transfer mode.

  2. In the method, if desired, changing the value of the variable structure, can be transmitted by way of pointers to structures, a structure pointer compared to such a large structure, the transmission value is smaller, more efficient, recommended!
    See the following example:

    package main
    import "fmt"
    
    type Circle struct {
    	Radius float64
    }
    func (cir Circle) area1(radius float64) float64 {    //没啥说的,值拷贝,即便定义了radius值,也不会影响main()中
    	pi := 3.141592653
    	mianji := pi * radius * radius
    	return mianji
    }
    
    func (cir *Circle) area2() float64 {              //推荐使用这种方式传递结构体变量
    	pi := 3.141592653                             //但是根据golang底层编译器设计,已经做了优化,等于所有地址,取值都不用了
    	(*cir).Radius = 20                            //函数体内修改指针地址对应的值,main()的cri.Radius也会发生变化,写成cir.Radius也行,编译器优化
    	mianji := pi * (*cir).Radius * (*cir).Radius  //mianji := pi * cir.Radius * cir.Radius 这样没有任何问题,cir = (*cir)
    	return mianji
    }
    
    func main() {
    	var cir = Circle{10}
    	area1 := cir.area1(cir.Radius)
    	fmt.Println("圆形的面积为:",area1)
    	area2 := (&cir).area2()                      //同上,area2 := cir.area2()也没有任何问题,cir = (&cir),仅仅限于此,为了安全还是都表明取址取值
    	fmt.Println("圆形的面积为:",area2)
    	fmt.Println(cir.Radius)                      //变为20了。
    }
    
  3. Not only the structure, float64, int can also have their own methods, and may reflect the value of the copy address Copy

    package main
    import "fmt"
    type Integer int
    
    func (i Integer) Print() {     //值拷贝,修改i的值不会影响到main的值
    	i++
    	fmt.Println("i= ",i)
    }
    
    func (i *Integer) change() {   //地址拷贝,函数内修改直接影响main中的值
    	*i++
    	fmt.Println("i= ",*i)
    }
    
    func main() {
    	var i Integer = 10
    	i.print()
    	fmt.Println(i)
    	i.change()
    	fmt.Println(i)
    }
    
  4. Methods and structures, as functions, variables, can be called the first letter capitalized in other packages.

  5. If a type implements string () This method, then fmt.Println () calls the string default this variable () output. This really is not well understood, but probably know what it means

    package main
    import "fmt"
    
    type Student struct {
    	Name string
    	Age int
    }
    
    func (stu *Student) String() string {
    	str := fmt.Sprintf("name = %v , age = %v",stu.Name,stu.Age)    //也就解释了第五条
    	return str
    }
    
    func main() {
    	var stu = Student{"durant",35}
    	fmt.Println(&stu)           //自动调用了String()方法后的输出    name = durant , age = 35
    	fmt.Println(stu)            //完全是通过main中传递,没有调用任何方法  {durant 35}
    }
    
Published 49 original articles · won praise 18 · views 4006

Guess you like

Origin blog.csdn.net/weixin_41047549/article/details/89973103