go object oriented programming

A program is a world with many objects (variables)

Description of object-oriented programming in Golang

1) Golang also supports object-oriented programming (OOP), but it is different from traditional object-oriented programming, and it is not a pure pair oriented programming
Like language. So we say that it is more accurate for Golang to support object-oriented programming features.
2) there is no class in golang. The struct of Go language has the same status as the class of other programming languages. You can
To understand that Golang is based on struct to implement OOP features.
3) the object-oriented programming of golang is very simple, which eliminates the inheritance, method overload, constructor and destructor of traditional OOP language
Number, hidden this pointer, etc

4) Golang still has the inheritance, encapsulation and polymorphism features of object-oriented programming, but its implementation mode and other OOP languages do not
For example, inheritance: Golang has no extensions keyword, and inheritance is implemented through anonymous fields.
5) Golang is very elegant in object-oriented (OOP). OOP itself is a part of the language type system through the interface
(interface) association, low coupling, and very flexible. That is to say, in Golang
Programming to interfaces is a very important feature.

Relationship between structure and structure variable (instance / object)

1) extract the characteristics of a kind of things (such as cats) to form a new data type, which is a structure.
2) with this structure, we can create multiple variables (instance / object)
3) things can be cat, Person, Fish or a tool class...

package main
import (
    "fmt"
)


//Define a Cat structure, put the fields / attribute information of Cat into the Cat structure for management
type Cat struct {
    Name string 
    Age int 
    Color string 
    Hobby string
    Scores [3]int // Fields are arrays
}

func main() {

    // Mrs. Zhang has 20 cats: one is Xiaobai, 3 years old, white. There's another one called Xiaohua,
    // It's 100 years old. It's decor. Please write a program to display the cat's name when the user enters it,
    // Age, color. If the cat name entered by the user is wrong, it shows that Mrs. Zhang does not have the cat.

    // //1. Handling of using variables
    // var cat1Name string = "small white"
    // var cat1Age int = 3
    // var cat1Color string = "white"

    // var cat2Name string = "floret"
    // var cat2Age int = 100
    // var cat2Color string = "Decor"

    // //2. Use array to solve
    // var catNames [2]string = [...]string {"little white", "little flower"}
    // var catAges [2]int = [...]int{3, 100}
    // var catColors [2]string = [...]string {"white", "Decor"}
    // //... map[string]string

    // fmt.Println("ok")

    // Using struct to complete the case

    // Create a Cat variable
    var cat1 Cat  // var a int
    
    fmt.Printf("cat1 Address=%p\n", &cat1)
    cat1.Name = "Xiao Bai"
    cat1.Age = 3
    cat1.Color = "white"
    cat1.Hobby = "eat<・)))><<"
    

    fmt.Println("cat1=", cat1)

    fmt.Println("Cat information is as follows:")
    fmt.Println("name=", cat1.Name)
    fmt.Println("Age=", cat1.Age)
    fmt.Println("color=", cat1.Color)
    fmt.Println("hobby=", cat1.Hobby)

    

}

The difference and connection between structural body and structural body variable (example)

We can see from the above cases and explanations:
1) a structure is a custom data type, representing a class of things
2) the structural variable (example) is concrete and practical, representing a specific variable
Layout of structure variables (instances) in memory (important!)

How to declare a structure

Basic grammar

type Structure name struct {
field1 type
field2 type
}
 //Give an example:
type Student struct {
Name string //field
Age int //field
Score float32
}

Fields / properties

Basic introduction
1) in terms of concept or nomenclature: structural field = attribute = field
2) a field is a component of a structure. It is generally a basic data type, an array, or a reference type. For example, we decided
The Name string of the Yimao structure is the attribute

Notes and details
1) the syntax of field declaration is the same as that of variable. Example: field name field type
2) the type of field can be: basic type, array or reference type
3) after creating a structure variable, if there is no value assigned to the field, it corresponds to a zero value (default value). The rules are the same as the above
Same:
The boolean type is false, the value is 0, and the string is' '.
The default value of array type is related to its element type. For example, score [3]int is [0, 0, 0]
The zero values of pointer, slice, and map are nil, i.e. no space has been allocated.
4) the fields of different structural variables are independent and do not affect each other. The change of one structural variable field does not affect the other
Is the value type.

package main
import (
    "fmt"
)

//If the field type of the structure is: nil for pointer, slice, and map, there is no space allocated
//If you need to use such a field, you need to make it before you can use it

type Person struct{
    Name string
    Age int
    Scores [5]float64
    ptr *int //Pointer 
    slice []int //Section
    map1 map[string]string //map
}

type Monster struct{
    Name string
    Age int
}


func main() {

    //Defining structural variables
    var p1 Person
    fmt.Println(p1)

    if p1.ptr == nil {
        fmt.Println("ok1")
    }

    if p1.slice == nil {
        fmt.Println("ok2")
    }

    if p1.map1 == nil {
        fmt.Println("ok3")
    }

    //Use slice, again, make sure
    p1.slice = make([]int, 10)
    p1.slice[0] = 100 //ok

    //To use map, make it first
    p1.map1 = make(map[string]string)
    p1.map1["key1"] = "tom~" 
    fmt.Println(p1)

    //The fields of different structural variables are independent and do not affect each other. The change of a structural variable field,
    //Does not affect the other, structure is value type
    var monster1 Monster
    monster1.Name = "King of cattle"
    monster1.Age = 500

    monster2 := monster1 //The structure is a value type, and the default is value copy
    monster2.Name = "Green cattle essence"

    fmt.Println("monster1=", monster1) //Monster 1 = {bull 500}
    fmt.Println("monster2=", monster2) //monster2 = {qingniujing 500}

}

Create structure variables and access structure fields

Mode 1 - direct statement

Case study: var person Person
We've already said that.

Mode 2-{}

Case study: var person Person = Person {}

Mode 3-&

Case: var person *Person = new (Person)

Mode 4-{}

Case: VAR person * person = & person {}

Explain:

1) methods 3 and 4 return structure pointer.
2) the standard way for a structure pointer to access a field is: (structure pointer). Field name, such as (person).Name = "tom"
3) however, go makes a simplification and supports structure pointer and field name, such as person.Name = "tom". More in line with programmers
Using habits, the go layer compiler underlayer has transformed the person.nameization (* person.Name)

package main
import (
    "fmt"
)

type Person struct{
    Name string
    Age int
}
func main() {
    //Mode 1

    //Mode 2
    p2 := Person{"mary", 20}
    // p2.Name = "tom"
    // p2.Age = 18
    fmt.Println(p2)

    //Mode 3-&
    //Case: var person *Person = new (Person)

    var p3 *Person= new(Person)
    //Because p3 is a pointer, the standard way to assign values to fields is
    //(* p3).Name = "smith" you can also write p3.Name = "smith"

    //Reason: for the convenience of programmers, the designer of go will process p3.Name = "smith" at the bottom
    //Value operation will be added to p3 (* p3).Name = "smith"
    (*p3).Name = "smith" 
    p3.Name = "john" //

    (*p3).Age = 30
    p3.Age = 100
    fmt.Println(*p3)

    //Mode 4-{}
    //Case: VAR person * person = & person {}

    //The following statement can also assign values directly to characters
    //var person *Person = &Person{"mary", 60} 
    var person *Person = &Person{}

    //Because person is a pointer, the standard way to access fields
    // (*person).Name = "scott"
    // For the convenience of programmers, the designer of go can also use person.Name = "scott"
    // The reason is the same as above. The underlying layer will process person.Name = "scott" and add (* person)
    (*person).Name = "scott"
    person.Name = "scott~~"

    (*person).Age = 88
    person.Age = 10
    fmt.Println(*person)

}

Memory allocation mechanism of struct type

slightly

Precautions and details for use of structure

1) all fields of the structure are continuous in memory

package main 
import "fmt"

//structural morphology
type Point struct {
    x int
    y int
}

//structural morphology
type Rect struct {
    leftUp, rightDown Point
}

//structural morphology
type Rect2 struct {
    leftUp, rightDown *Point
}

func main() {

    r1 := Rect{Point{1,2}, Point{3,4}} 

    //r1 has four int s, which are continuously distributed in memory
    //Print address
    fmt.Printf("r1.leftUp.x address=%p r1.leftUp.y address=%p r1.rightDown.x address=%p r1.rightDown.y address=%p \n", 
    &r1.leftUp.x, &r1.leftUp.y, &r1.rightDown.x, &r1.rightDown.y)

    //r2 has two * Point types. The addresses of these two * Point types are also consecutive,
    //But the addresses they point to are not necessarily consecutive

    r2 := Rect2{&Point{10,20}, &Point{30,40}} 

    //Print address
    fmt.Printf("r2.leftUp Own address=%p r2.rightDown Own address=%p \n", 
        &r2.leftUp, &r2.rightDown)

    //The addresses they point to are not necessarily consecutive... It depends on how the system is allocated at runtime
    fmt.Printf("r2.leftUp Pointing address=%p r2.rightDown Pointing address=%p \n", 
        r2.leftUp, r2.rightDown)

}

2) the structure is a type defined by the user independently. When converting with other types, it needs to have exactly the same fields (name, number and class)
Type)
3) the type of the structure is redefined (equivalent to taking an alias). Golang thinks that it is a new data type, but it can transform strongly between them
4) on each field of struct, you can write a tag, which can be obtained through reflection mechanism. The common use scenario is sequence
Listing and deserializing

package main 
import "fmt"
import "encoding/json"

type A struct {
    Num int
}
type B struct {
    Num int
}

type Monster struct{
    Name string `json:"name"` // `json:"name" is struct tag
    Age int `json:"age"`
    Skill string `json:"skill"`
}
func main() {
    var a A
    var b B
    a.Num=1
    b.Num=2
    a = A(b) // ? it can be converted, but it is required that the fields of the structure should be exactly the same (including name, number and type! )
    fmt.Println(a, b)

    //1. Create a Monster variable
    monster := Monster{"King of cattle", 500, "Palm fan~"}

    //2. Serialize the monster variable into json format string
    //   Reflection is used in json.Marshal function. When reflection is used, it is introduced in detail
    jsonStr, err := json.Marshal(monster)
    if err != nil {
        fmt.Println("json Handling errors ", err)
    }
    fmt.Println("jsonStr", string(jsonStr))

}

Method

Basic introduction

In some cases, we need to declare (define) methods. For example, Person structure: in addition to some fields (age, last name
Person structure also has some behaviors, such as speaking, running, learning and doing arithmetic problems. At this time, we need to use methods to complete.
The methods in Golang act on the specified data type (i.e. bind to the specified data type), so the custom type,
There can be methods, not just struct s.

Method declaration and call

typeAstruct {
Num int
}
func (aA) test() {
fmt.Println(a.Num)
}

**A description of the above syntax**
1) func (aA) test() {} indicates that A structure has A method named test
2) (aA) indicates that the test method is bound to type A

package main

import (
    "fmt"   
)

type Person struct {
    Name string
} 

//function
//For normal functions, when the receiver is of value type, data of pointer type cannot be passed directly, and vice versa

func test01(p Person) {
    fmt.Println(p.Name)
}

func test02(p *Person) {
    fmt.Println(p.Name)
}

//For methods such as struct,
//When the receiver is of value type, the method can be called directly with variable of pointer type, and vice versa

func (p Person) test03() {
    p.Name = "jack"
    fmt.Println("test03() =", p.Name) // jack
}

func (p *Person) test04() {
    p.Name = "mary"
    fmt.Println("test03() =", p.Name) // mary
}

func main() {

    p := Person{"tom"}
    test01(p)
    test02(&p)

    p.test03()
    fmt.Println("main() p.name=", p.Name) // tom
    
    (&p).test03() // Formally, it's an incoming address, but essentially it's still a copy of the value

    fmt.Println("main() p.name=", p.Name) // tom


    (&p).test04()
    fmt.Println("main() p.name=", p.Name) // mary
    p.test04() // E & quivalence. Test04, formally an incoming value type, but essentially an address copy

}

Summary of the above
1) test method and Person type binding
2) the test method can only be called through a variable of type Person, not directly, or other variables
use
3) func (p Person) test() {}... p indicates which Person variable is called, and this p is its copy, which is different from the function parameter
Constant similarity.
4) the name P is specified by the programmer, not fixed. For example, it can be changed to person

Method quick start

1) add the speak method to the Person structure and output xxx as a good Person
2) add jisuan method to the Person structure to calculate the result from 1 +.. + 1000, which shows that the function in the method body can be the same,
Perform various operations
3) give the Person structure jisuan2 method, which can receive a number N and calculate the result from 1+..+n
4) add the getSum method to the Person structure to calculate the sum of two numbers and return the result
5) method call

package main

import (
    "fmt"   
)

type Person struct{
    Name string
}

//Add the speak method to the Person structure and output xxx as a good Person
func (p Person) speak() {
    fmt.Println(p.Name, "It is a goodman~")
}

//Add jisuan method to Person structure to calculate the result from 1 +.. + 1000, 
//It shows that all kinds of operations can be performed in the body of the method just like functions

func (p Person) jisuan() {
    res := 0
    for i := 1; i <= 1000; i++ {
        res += i
    }
    fmt.Println(p.Name, "The result of the calculation is=", res)
}

//Give the Person structure jisuan2 method, which can receive a parameter n and calculate the result from 1+..+n
func (p Person) jisuan2(n int) {
    res := 0
    for i := 1; i <= n; i++ {
        res += i
    }
    fmt.Println(p.Name, "The result of the calculation is=", res)
}

//Add the getSum method to the Person structure to calculate the sum of two numbers and return the result
func (p Person) getSum(n1 int, n2 int) int {
    return n1 + n2
}

//Bind a method to the Person type
func (person Person) test() {
    person.Name = "jack"
    fmt.Println("test() name=", person.Name) // Output jack
}

type Dog struct {

}

func main() {

    var p Person
    p.Name = "tom"
    p.test() //Calling method
    fmt.Println("main() p.Name=", p.Name) //Output tom
    //The following ways of use are all wrong
    // var dog Dog  
    // dog.test()
    // test()

    //Calling method
    p.speak()
    p.jisuan()
    p.jisuan2(20)
    n1 := 10
    n2 := 20
    res := p.getSum(n1, n2)
    fmt.Println("res=", res)
}

Method call and parameter passing mechanism principle: (important! )

Explain:

The method call and parameter passing mechanism are basically the same as functions. The difference is that when a method is called, the variables that call the method are used as
Arguments are also passed to methods. Let's give an example.

Explain:

1) when a method is called through a variable, its calling mechanism is the same as that of a function
2) when a variable calls a method in a different place, the variable itself will also be passed to the method as a parameter (if the variable is a value class)
Type, copy the value; if the variable is of reference type, copy the geological value.)

Case 2

Please write a program with the following requirements:
1) declare a structure Circle with the field radius
2) declare a method area and Circle binding to return area.

package main

import (
    "fmt"   
)

type Circle struct {
    radius float64
}

//2) declare a method area and Circle binding to return area.

func (c Circle) area() float64 {
    return 3.14 * c.radius * c.radius
}

//In order to improve efficiency, we usually bind pointer types of methods and structures
func (c *Circle) area2() float64 {
    //Because C is a pointer, our standard way to access its fields is (* c).radius
    //return 3.14 * (*c).radius * (*c).radius
    // (* c).radius equivalent c.radius 
    fmt.Printf("c yes  *Circle Address to=%p", c)
    c.radius = 10
    return 3.14 * c.radius * c.radius
}
 
func main() {
// 1) declare a structure Circle with the field radius
// 2) declare a method area and Circle binding to return area.
// 3) prompt: draw area execution process + description

    //Create a Circle variable
    // var c Circle 
    // c.radius = 4.0
    // res := c.area()
    // fmt.Println("area =", res)

    //Create a Circle variable
    var c Circle 
    fmt.Printf("main c Structure variable address =%p\n", &c)
    c.radius = 7.0
    //res2 := (&c).area2()
    //C.area() is equivalent to c.area()
    //Because the compiler will automatically add & C
    res2 := c.area2()
    fmt.Println("The measure of area=", res2)
    fmt.Println("c.radius = ", c.radius) //10


}

Method declaration (definition)

Func (receiver type) methodname (parameter list) (return value list){
Method body
 Return return value
}

1) parameter list: representation method input
2) receiver type: indicates that the method is bound to the type, or that the method acts on the type
3) receiver type: type can be a structure or other user-defined type
4) receiver: a variable (instance) of type, such as a variable (instance) of Person structure
5) return value list: indicates the returned value, which can be multiple
6) method body: means to implement a function code block
7) the return statement is not required.

Method considerations and details

1) the structure type is the value type. In the method call, the value copy delivery mechanism is obeyed
2) if the programmer wants to modify the value of the structure variable in the method, it can be handled by the structure pointer.
3) the methods in golang act on the specified data type (i.e. bind to the specified data type), so the user-defined type,
There can be methods, not just struct, such as int, float32, etc

package main

import (
    "fmt"   
)
/*
Golang The method in the acts on the specified data type (that is, it is bound to the specified data type), so the custom type,
There can be methods, not just struct, such as int, float32, etc
*/

type integer int

func (i integer) print() {
    fmt.Println("i=", i)
}
//Write a method to change the value of i
func (i *integer) change() {
    *i = *i + 1
}

type Student struct {
    Name string
    Age int
}

//Implement method String() for * Student
func (stu *Student) String() string {
    str := fmt.Sprintf("Name=[%v] Age=[%v]", stu.Name, stu.Age)
    return str
}

func main() {
    var i integer = 10
    i.print()
    i.change()
    fmt.Println("i=", i)

    //Define a Student variable
    stu := Student{
        Name : "tom",
        Age : 20,
    }
    //If you implement a String method of type * Student, it will be called automatically
    fmt.Println(&stu) 
} 

A few small examples

1) write method utils, program a method, the method does not need parameters, print a 108 rectangle in the method,
Invoke the method in the main method.
2) write a method to provide m and n parameters, in which a mn rectangle is printed
3) write a method to calculate the area of the rectangle (it can receive long len and wide width) as the return value of the method. At main
This method is called in the method to receive the returned area value and print it.
4) compilation method: judge whether a number is odd or even
5) print the characters corresponding to the number of rows and columns according to the row, column and character, for example: row: 3, column: 2, character *, then print the corresponding effect
fruit
6) define the calculator and realize the four functions of addition, subtraction, multiplication and division
Implementation form 1: it is completed in four ways:
Implementation form 2: one way

package main

import (
    "fmt"   
)

type MethodUtils struct {
    //Field...
}

//Write methods for MethodUtils
func (mu MethodUtils) Print() {
    for i := 1; i <= 10; i++ {
        for j := 1; j <= 8; j++ {
            fmt.Print("*")
        }
        fmt.Println()
    }
}

//2) write a method to provide m and n parameters, in which a rectangle of m*n is printed
func (mu MethodUtils) Print2(m int, n int) {
    for i := 1; i <= m; i++ {
        for j := 1; j <= n; j++ {
            fmt.Print("*")
        }
        fmt.Println()
    }
}

/*
Write a method to calculate the area of the rectangle (it can receive long len and wide width), 
Return it as a method return value. Invoke the method in the main method, receive the returned area value and print it.
*/

func (mu MethodUtils) area(len float64, width float64) (float64) {
    return len * width
}

/*
Compiling method: judge whether a number is odd or even

*/

func (mu *MethodUtils) JudgeNum(num int)  {
    if num % 2 == 0 {
        fmt.Println(num, "Even numbers..")   
    } else {
        fmt.Println(num, "It's odd...")   
    }
}
/*
Print the characters corresponding to the number of rows and columns according to rows, columns and characters,
For example: Line: 3, column: 2, character *, print the corresponding effect

*/

func (mu *MethodUtils) Print3(n int, m int, key string)  {
    
    for i := 1; i <= n ; i++ {
        for j := 1; j <= m; j++ {
            fmt.Print(key)
        }
        fmt.Println()
    }
}

/*
Define the calculator,
Four functions of addition, subtraction, multiplication and division
 Implementation form 1: completed in four ways: calculate + - * respectively/
Implementation form 2: it can be done in one way. It needs to receive two numbers and an operator 

*/
//Implementation form 1

type Calcuator struct{
    Num1 float64
    Num2 float64
}

func (calcuator *Calcuator) getSum() float64 {

    return calcuator.Num1 + calcuator.Num2
}

func (calcuator *Calcuator) getSub() float64 {

    return calcuator.Num1 - calcuator.Num2
}

//..

//Implementation form 2

func (calcuator *Calcuator) getRes(operator byte) float64 {
    res := 0.0
    switch operator {
    case '+':
            res = calcuator.Num1 + calcuator.Num2
    case '-':
            res = calcuator.Num1 - calcuator.Num2
    case '*':
            res = calcuator.Num1 * calcuator.Num2
    case '/':
            res = calcuator.Num1 / calcuator.Num2
    default:
            fmt.Println("Wrong operator input...")
            
    }
    return res
}


func main() {
    /*
    1)Write method utils, program a method, the method does not need parameters,
    Print a 10*8 rectangle in the method and call the method in the main method.
    */
    var mu MethodUtils
    mu.Print()
    fmt.Println()
    mu.Print2(5, 20)

    areaRes := mu.area(2.5, 8.7)
    fmt.Println()
    fmt.Println("Area is=", areaRes)

    mu.JudgeNum(11)

    mu.Print3(7, 20, "@")


    //Test it:
    var calcuator Calcuator
    calcuator.Num1 = 1.2
    calcuator.Num2 = 2.2
    fmt.Printf("sum=%v\n", fmt.Sprintf("%.2f",calcuator.getSum()))
    fmt.Printf("sub=%v\n",fmt.Sprintf("%.2f",calcuator.getSub()))


    res := calcuator.getRes('*')
    fmt.Println("res=", res)

}

Difference between methods and functions

1) different calling methods
Function call method: function name (argument list)
Method call method: variable. Method name (argument list)
2) for ordinary functions, when the receiver is of value type, data of pointer type cannot be transferred directly, and vice versa
3) for methods (such as struct), when the receiver is of value type, the method can be called directly with variables of pointer type
Come here, too

package main

import (
    "fmt"   
)

type Person struct {
    Name string
} 

//function
//For normal functions, when the receiver is of value type, data of pointer type cannot be passed directly, and vice versa

func test01(p Person) {
    fmt.Println(p.Name)
}

func test02(p *Person) {
    fmt.Println(p.Name)
}

//For methods such as struct,
//When the receiver is of value type, the method can be called directly with variable of pointer type, and vice versa

func (p Person) test03() {
    p.Name = "jack"
    fmt.Println("test03() =", p.Name) // jack
}

func (p *Person) test04() {
    p.Name = "mary"
    fmt.Println("test03() =", p.Name) // mary
}

func main() {

    p := Person{"tom"}
    test01(p)
    test02(&p)

    p.test03()
    fmt.Println("main() p.name=", p.Name) // tom
    
    (&p).test03() // Formally, it's an incoming address, but essentially it's still a copy of the value

    fmt.Println("main() p.name=", p.Name) // tom


    (&p).test04()
    fmt.Println("main() p.name=", p.Name) // mary
    p.test04() // E & quivalence. Test04, formally an incoming value type, but essentially an address copy

}

Conclusion:
1) regardless of the calling form, it really decides whether to copy the value or the address, depending on which type this method is bound to
2) if it is a sum value type, such as (p Person), it is a value copy. If it is a sum value type, such as (p *Person), it is a value copy
Is an address copy.

An application example of object-oriented programming

step

1) declare (define) the structure and determine its name
2) write the fields of the structure
3) method of compiling structure

Student case:

1) write a Student structure, including name, gender, age, id and score fields, which are string, string, int
int, float64 type.
2) declare a say method in the structure, return string type, and the method return information contains all field values.
3) in the main method, create the Student structure instance (variable), access the say method, and print the result.
4) go code

import (
"fmt"
)
/*
Student case:
Write a Student structure, including name, gender, age, id, score fields, which are string, string, int, int
float64 Type.
A say method is declared in the structure, which returns the string type. The return information of the method contains all the field values.
In the main method, create an instance of the Student structure (variable), access the say method, and print out the result.
*/
type Student struct {
    name string
    gender string
    age int
    id int
    score float64
}
func (student *Student) say() string {
    infoStr := fmt.Sprintf("student Information name=[%v] gender=[%v], age=[%v] id=[%v] score=[%v]",
    student.name, student.gender, student.age, student.id, student.score)
    return infoStr
}
func main() {
//test
//Create a Student instance variable
var stu = Student{
    name : "tom",
    gender : "male",
    age : 18,
    id : 1000,
    score : 99.98,
}
   fmt.Println(stu.say())
}

Box case

1) program to create a Box structure, in which three fields are declared to represent the length, width and height of a cube, and the length, width and height should be from the end
End access
2) declare a method to get the volume of the cube.
3) create a Box structure variable and print the volume of the cube of the given size
4) go code

Ticket cases

1) a scenic spot charges tickets of different prices according to the age of tourists, for example, if the age is more than 18, 20 yuan will be charged, otherwise the tickets will be free
Fei.
2) please write Visitor structure, determine the ticket price that can be purchased according to the age group and output
3) code:

package main

import (
    "fmt"   
)

/*
Student case:
Write a Student structure, including name, gender, age, id, score fields, which are of string, string, int, int, float64 types.
A say method is declared in the structure, which returns the string type. The return information of the method contains all the field values.
In the main method, create an instance of the Student structure (variable), access the say method, and print out the result.

*/
type Student struct {
    name string
    gender string
    age int
    id int
    score float64
}

func (student *Student) say()  string {

    infoStr := fmt.Sprintf("student Information name=[%v] gender=[%v], age=[%v] id=[%v] score=[%v]",
        student.name, student.gender, student.age, student.id, student.score)

    return infoStr
}

/*
1)Program to create a Box structure, in which three fields are declared to represent the length, width and height of a cube. The length, width and height should be obtained from the terminal
2)Declare a method to get the volume of the cube.
3)Create a Box structure variable to print the volume of a given size cube
*/
type Box struct {
    len float64
    width float64
    height float64
}

//Declare a method to get the volume of cube
func (box *Box) getVolumn() float64 {
    return box.len * box.width * box.height
}


// Ticket cases

// A scenic spot charges tickets of different prices according to the age of tourists, for example, if the age is more than 18, 20 yuan will be charged, and other tickets will be free
// Please write the Visitor structure, determine the ticket price that can be purchased according to the age group and output

type Visitor struct {
    Name string
    Age int
}

func (visitor *Visitor) showPrice() {
    if visitor.Age >= 90 || visitor.Age <=8 {
        fmt.Println("Don't play for safety")
        return 
    }
    if visitor.Age > 18 {
        fmt.Printf("The name of the tourist is %v Age is %v The charge is 20 yuan. \n", visitor.Name, visitor.Age)
    } else {
        fmt.Printf("The name of the tourist is %v Age is %v Free Admission \n", visitor.Name, visitor.Age)
    }
}



func main() {
    //test
    //Create a Student instance variable
    var stu = Student{
        name : "tom",
        gender : "male",
        age : 18,
        id : 1000,
        score : 99.98,
    }
    fmt.Println(stu.say())

    //Test code
    var box Box
    box.len = 1.1
    box.width = 2.0
    box.height = 3.0
    volumn := box.getVolumn()
    fmt.Printf("Volume is=%.2f", volumn)


    //test
    var v Visitor
    for {
        fmt.Println("Please enter your name")
        fmt.Scanln(&v.Name)
        if v.Name == "n" {
            fmt.Println("Exit procedure....")
            break
        }
        fmt.Println("Please enter your age")
        fmt.Scanln(&v.Age)
        v.showPrice()

    }
}

Specify field values when creating structure variables

Explain
When Golang creates a structure instance (variable), it can directly specify the value of the field

package main

import (
    "fmt"   
)
type Stu struct {
    Name string
    Age int
}

func main() {

    //Mode 1
    //When you create a structure variable, you specify the value of the field directly
    var stu1 = Stu{"Xiao Ming", 19} // Stu1 - > structure data space
    stu2 := Stu{"Xiao Ming~", 20}

    //When creating structural variables, the field name and field value are written together, which does not depend on the definition order of the field
    var stu3 = Stu{
            Name :"jack",
            Age : 20,
        }
    stu4 := Stu{
        Age : 30,
        Name : "mary",
    }
    
    fmt.Println(stu1, stu2, stu3, stu4)

    //Mode 2, return the pointer type of the structure (!!)
    var stu5 *Stu = &Stu{"Xiao Wang", 29}  // Stu5 -- > address - - structure data [xxxx,xxx]
    stu6 := &Stu{"Xiao Wang~", 39}

    //When creating structure pointer variables, the field name and field value are written together, which does not depend on the definition order of the field
    var stu7 = &Stu{
        Name : "petty thief",
        Age :49,
    }
    stu8 := &Stu{
        Age :59,
        Name : "petty thief~",
    }
    fmt.Println(*stu5, *stu6, *stu7, *stu8) //

}

Factory mode

The structure of Golang does not have a constructor, and you can usually use factory mode to solve this problem.

Look at a need

The declaration of a structure is as follows:
package model
type Student struct {
Name string...
}
Because the initial S of the Student here is uppercase. If we want to create an instance of the Student in another package (such as the main package),
After the model package is introduced, the variables (instances) of the Student structure can be created directly But the problem is, if the initial is lowercase,
For example, the type student struct {....} is not good. How to do it -- > factory mode

Factory model to solve problems

Use factory mode to create a case of structure instance (variable) across packages:
If the initial of the structure variable of the model package is capitalized, it can be used directly after being introduced. There is no problem
If the structure variable of the model package has lowercase initial, it can not be used directly after being introduced. It can be solved by factory mode and watched by the teacher.
Code:
student.go

package model

//Define a structure
type student struct{
    Name string
    score float64
}

//Because the initial of the student structure is lowercase, it can only be used in the model
//We solve it through the factory model

func NewStudent(n string, s float64) *student {
    return &student{
        Name : n,
        score : s,
    }
}

//If the score field starts in lowercase, you can't directly use it in other packages. We can provide a method
func (s *student) GetScore() float64{
    return s.score //ok
}

main.go

package main
import (
    "fmt"
    "go_code/chapter10/factory/model"
)

func main() {
    //Create an instance for Student
    // var stu = model.Student{
    //  Name :"tom",
    //  Score : 78.9,
    // }

    //The fixed student structure is lowercase, which can be solved by factory mode
    var stu = model.NewStudent("tom~", 98.8)

    fmt.Println(*stu) //&{....}
    fmt.Println("name=", stu.Name, " score=", stu.GetScore())
}

Tags: Go Programming JSON Attribute calculator

Posted on Thu, 07 Nov 2019 14:51:26 -0500 by thumrith