Go language self-study notes (d)

Disclaimer: This article is a blogger original article, follow the CC 4.0 BY-SA copyright agreement, reproduced, please attach the original source link and this statement.
This link: https://blog.csdn.net/qq_18800771/article/details/97250277

Object-oriented programming: inheritance, encapsulation, polymorphism, reuse, multithreading, low coupling.

Package: achieved by the method.

Inheritance: is achieved by an anonymous field.

Polymorphism: via interface.

Anonymous field in Go / anonymous Portfolio / embedded fields:

Anonymous field structure type: anonymous member variable field will inherit both fields, will inherit the field method (method Detailed below).

type Person struct{
    name string
    sex byte
    age int
}
type Student struct{
    Person    //匿名字段,只有类型,没有名字。继承字段实现代码复用即继承了Person全部成员
    id int
    addr string
}
func (tmp *Person) PrintInfo(){    //Person实现的方法,通过匿名字段可以被Student调用
    fmt.Printf("name=%s, sex=%c, age=%d\n",tmp.name,tmp.sex,tmp.age)
}

Anonymous field initialization:

Order of initialization / Full Initialization:

var s1 Student = Student{Person{"tom",'m',18},1,"北京"}
fmt.Printf("s = %+v",s)    //格式化打印:%+v占位,详细输出

Designated member initialization, uninitialized members automatically assigned to 0:

s2:=Student{Person:Person{name:"tom"},addr:"北京"}

Operation members: fully consistent with the structure

Anonymous whole field assignment:

s1.Person=Person{"tom",'m',18}

Anonymous treatment of the same name field fields:

type Person struct{
    name string
    sex byte
    age int
}
type Student struct{
    Person
    id int
    addr string
    name string    //同名字段
}

Assignment field of the same name: the principle of proximity, the same as the namesake local / global variable rules. If you can find this member in the scope of this play to do if the find did not find Fields inherited operations. Direct operating field of the same name inherited field, then use the following syntax: explicit call

s1.Person.name = "go"

Non-anonymous field structure:

type Person struct{
    name string
    sex byte
    age int
}
type Student struct{
    Person    //结构体匿名字段
    int        //非结构体匿名字段
    string
}

No difference between normal structure the assignment, but it should be noted that when using a non-anonymous field structure, you can directly use the type name instead of using the member name. Such as:

s1.Person
s1.int

Type structure pointer field Anonymous:

type Student struct{
    *Person    //指针匿名字段
    id int
    addr string
}

Anonymous pointer field is initialized: Only when the memory address of a pointer type overall print.

Direct initialization:

s1 := Student{&Person{"tom",'m',18},1,"北京"}

Space allocation and assignment Initialization:

var s2 Student
s2.Person=new(Person)    //分配空间
s2.name="tom"
s2.sex='m'
s2.age=18
s2.id=1
s2.addr="北京"

The method / method Method tie function: func (reviver Type) funname () {}

Receiver reciver, binding type Type. Function is called with the recipient's method.

Discuss the differences disguised object functions for process and by the process of:

Process-oriented:

func add(a,b int)int{
    return a+b
}
func main(){
    result:=add(1,1)
}

Object-oriented:

type long int    //int别名为long
func (tmp long) add(other long) long{    //add方法绑定类型接收者,tmp接收者,就是一个传递参数
    return tmp+other
}
func main(){
    var a long = 2
    result:=a.add(3)    //调用格式:变量名.函数(参数)
}

Note that: Go language is very strict type checking, this time with a long int can not receive each other. Object-oriented functions just changed a form of expression.

Add structure type binding function method:

type Person struct{
    name string
    sex byte
    age int
}
func (tmp Person) PrintInfo(){
    fmt.Println(tmp)
}
func main(){
    p:=Person{"tom",'m',18}
    p.PrintInfo()
}

Pointer as the recipient:

func (p *Person) SetInfo(n string,s byte,a int){
    p.name=n
    p.sex=s
    p.age=a
}
func main(){
    var p2 Person
    (&p2).SetInfo("tom",'m',18)
    p2.PrintInfo()
}

Note that: the recipient is not original pointer type, does not support overloaded methods / Duplicate definition (different types of receivers, do not overload the method of the same name).

Value and reference semantics Semantic: delivery type

Receivers as ordinary variables: value semantics (copy)

func (p Person) SetInfoValue(n string,s byte,a int){
    p.name=n
    p.sex=s
    p.age=a
}
func main(){
    s1:=new(Person)
    s1.SetInfoValue("tom",'m',18)
}

Recipient pointer variables: reference semantics (delivery address)

func (p *Person) SetInfoValue(n string,s byte,a int){
    p.name=n
    p.sex=s
    p.age=a
}
func main(){
    s1:=new(Person)
    (&s1).SetInfoValue("tom",'m',18)
}

Go methodologies language: the method defined variable is the set of methods that can be invoked.

Pointer variable call ordinary variables:

Normal call: (* p) .SetInfoValue ()

Internal conversion: p.SetInfoValue () put into the pointer p * p and then call

Call pointer variable pointer variable:

Normal call: p.SetInfoPointer ()

Internal conversion: (* p) .SetInfoValue () first converted into p * p and then call

Call pointer variable pointer variable:

Internal conversion: p.SetInfoPointer () inside the first p & p then call into

Common variable call ordinary variables:

Normal call: p.SetInfoValue ()

Summary: with examples of value and call the method pointer (with anonymous field) bound by the method set, the compiler always looks for all methods, and automatic conversion receiver argument.

Inherited methods: Method can be inherited by an anonymous field to other structures, other structures can be called directly.

Rewrite / methods of the same name:

type Person struct{
    name string
    sex byte
    age int
}
type Student struct{
    Person
    id int
    addr string
}
func (tmp *Person) PrintInfo(){    //Person实现的方法,通过匿名字段可以被Student调用
    fmt.Printf("name=%s, sex=%c, age=%d\n",tmp.name,tmp.sex,tmp.age)
}
func (tmp *Student) PrintInfo(){    //Srudent实现的同名方法
    fmt.Printfln(tmp)
}

It calls the same method: the principle of proximity, priority scope of this method. If direct manipulation of the same name inherited methods, the explicit method is required.

s.Person.PrintInfo()

Methods values ​​and methods of expression:

func (p Person) SetInfoValue(){
    fmt.Printf("SetInfoValue: %p, %v\n", &p, p)
}
func (p *Person) SetInfoPointer(){
    fmt.Printf("SetInfoPointer: %p, %v\n", p, p)
}

Method Value: using a function pointer.

p.SetInfoPointer()    //传统调用方式
pFunc:=p.SetInfoPointer    //方法值保存函数入口
pFunc()    //调用函数,不需要再传递接收者,接收者被隐藏

Method expression:

f1:=(*Person).SetInfoPointer    //显式传递接收者
f1(&p)        //也可去掉&
f2:=(Person).SetInfoValue
f2(p)

Go language interface: describes the combination of a range of methods, not only declare the function is instantiated. Concerned only with behavior implemented.

Interface definition:

type Humaner interface{
    sayhi()        //只有声明,由自定义类型实现
}

Implementation of the interface:

func (tmp *Student) sayhi(){
   }

Interface variable definition and assignment, call:

var i Humaner
s:=&Student{}
i=s
i.sayhi()    //只要实现了此接口方法的类型,那么这个类型的变量就可以给i赋值,调用自动匹配方法

Multi-states: an ordinary function defining parameters, the function of the interface type:

func WhoSayHi(i Humaner){
    i.sayhi()    //只有一个函数,拥有不同表现--多态
}

Interface calls:

WhoSayHi(s)    //普通调用
x:=make([]Humaner, 1)    //创建切片
x[0]=s
for _,data:=range x{    //通过迭代调用
    i.sayhi()
}

Interface inheritance:

type Humaner interface{    //子集
    sayhi()
}
type Personer interface{    //超集
    Humaner    //匿名字段,继承了sayhi()
    sing(lrc string)    //含有参数的方法
}
func (tem *Student) sayhi(){
}
func (tem *Student) saing(lrc string){
}
func main(){
    var i Personer
    s:=&Student{}
    i=s
    i.sayhi()    //继承的方法
    i.sing("song")
}

Interface Converter: a superset of the variables can be converted to a subset of, but not vice versa

var iPro Personer    //超集
var i Humaner    //子集
iPro=i    //err
i=iPro

Air interface types: universal type, you can hold any type of value. There is no way, all types implement this interface.

var i interfave{}=1
i="abc"
var a []int        //切片空接口
var b []interface{}        //空接口

Parameter is empty interface function of the type:

func fun(args ...interface{}){
}    //可以报错0-多个不限类型的参数

Type Assertion / query type:

By type if assertion:

func main(){
    i := make([]interface{}, 3)
	i[0] = 1    //int
    i[1] = "hello go"    //string
    i[3] = Student{}    //struct
    for index, data := range i{        //index返回的是下标,data返回空接口变量
        if value, ok := data.(int); ok==true{        //value返回接口变量本身,ok返回bool类
            fmt.Printf("x[%d] 类型为int,内容为%d\n", index, value)
        }else if value, ok := data.(string); ok==true{
            fmt.Printf("x[%d] 类型为string,内容为%s\n", index, value)
        }else if value, ok := data.(Student); ok==true{
            fmt.Printf("x[%d] 类型为Student,内容为name=%s,id=%d\n", index, value.name, value.id)
        }
}

By type of switch assertion:

for index, data := range i{
    switch value := data.(type){
    case int:
        fmt.Printf("x[%d] 类型为int,内容为%d\n", index, value)
    case string:
        fmt.Printf("x[%d] 类型为string,内容为%s\n", index, value)
    case Student:
        fmt.Printf("x[%d] 类型为Student,内容为name=%s,id=%d\n", index, value.name, value.id)
    }
}

By type of formatted output asserts:

for index, data := range i{
    fmt.Printf("x[%d]的类型为%T,内容为%v\n", index, value, value)
}    //自动类型的类型断言

 

Guess you like

Origin blog.csdn.net/qq_18800771/article/details/97250277