Go语言结构体基础

struct初始化

1,定义

结构体是一种自定义数据类型,不是变量。只是一种存储数据结构的描述。
并不占用内存地址。实例化之后才会真正的占用内存地址。

type Name struct {
    a int
    b string
    c interface
}

2,实例化

1,定义变量实例化

    var ins T   //类似与用当前结构体类型定义一个变量

2,new实例化

    ins := new(T)

    ins是指针类型的结构体,*T

3,取地址实例化

    ins := &T{}


注意:
    1,new,取地址得到的是指针类型的结构体,比较常用。var定义的是非指针类型的结构体。
    2,取地址实例化方式是平时开发中最常见的实例化方式

3,成员变量

1,键值对初始化:

    //普通结构体
    ins := structName {
        key1:val1,
        key2:val2,
        ...
    }

    //指针结构体
    ins := &structName {
        key1:val1,
        key2:val2,
        ...
    }

2,值列表初始化

    //定义结构体
    type T struct {
        a:int
        b:int
        c:string
        d:bool
    }

    //普通结构体
    ins := T{
        1,
        2,
        "abc"
        true
    }

    //指针结构体
    ins := &T{
        1,
        2,
        "abc"
        true
    }

    注意:

        必须初始化结构体的所有字段。
        每一个初始值的填充顺序必须与字段在结构体中的声明顺序一致。
        键值对与值列表的初始化形式不能混用


3,匿名结构体初始化

    ins := struct{
        key1 int 
        key2 int
        key3 string
        key4 bool
    }{
        2,
        4,
        "hello world"
        true
    }

struct构造函数

1,概览:

go语言没有类的概念,所以没有构造函数。
但是可以根据结构体初始化的过程模拟实现构造函数的功能

go语言也没有继承的概念,定义子类结构体的时候,把父类嵌入来模拟继承。
这样的话,子类拥有所有父类的方法,属性。可直接调用

2,实例:

1,简单结构体实例化

    type Dog struct {
        Color string
        Name string
    }

    func NewDog(color,name string) *Dog{
        return &Dog{
            Name:name,
            Color:color,
        }
    }


    说明:
        通过调用NewDog函数,可以拿到实例化,且初始化之后的机构体。
        可以理解NewDog函数为Dog结构体的构造函数



2,父子关系结构体实例化:

    type Dog struct {
        Color string
        Name string
    }

    func (d *Dog) eat() {
        fmt.Println("狗狗要吃吃")
    }

    //类似于面向对象的继承,黑狗拥有狗的所有属性,方法
    type BlackDog struct {
        Dog
    }


    func NewBlackDog(color,name string ) *BlackDog {
        //取地址实例化BlackDog的同时,所继承的所有祖宗都会实例化。
        //然后孙子可以有所有祖宗的属性,方法
        //注意,这里不能直接取指针初始化,要实例化之后赋值
        blackDogs := &BlackDog{}
        blackDogs.Color = color
        blackDogs.Name = name
        return blackDogs
    }

    func main(){
        blackDog := NewBlackDog
        fmt.Println(blackDog)
        blackDog.eat()
    }

    说明:
        1,面向对象类的继承用extends,机构体模拟继承父类在定义子类的时候,父类作为其成员嵌入即可
        2,孙子结构体取指针实例化,同时祖宗结构体皆实例化。
        3,孙子结构体实例化之后,可拥有所有祖宗结构体的属性和方法

go语言方法和接收器

1,概览

1,go语言方法,作用在接收器上的函数。接收器几乎可以是任何变量类型。
2,接收器不可以是指针类型,但是可以是允许类型的指针。这里注意区分指针类型和类型的指针。go语言接收器也不允许是接口类型
3,类型 T(或 T)上的所有方法的集合叫做类型 T(或 T)的方法集

2,实例

type T struct {

}

//指针类型接收器
func (t *T) T_func_1(){

}

//非指针类型接收器
func (t T) T_func_2(){

}

func main() {
    tObj := &T
    tObj.T_func_1()
    tObj.T_func_2()
}

3,关于指针类型的接收器

1,指针类型的接收器由一个结构体的指针组成,更接近于面向对象中的 this 或者 self。
2,指针接收器调用方法时,修改接收器指针的任意成员变量,在方法结束后,修改都是有效的。

4,非指针接收器

1,非指针接收器,go语言运行代码时,会复制一份接收器的值。
所以在非指针接收器的方法中可以获取成员值,但是无法修改或修改无效

5,指针接收器和非指针接收器的选择参考

计算机中,小对象值复制速度较快,适用于非指针接收器
大对象复制性能差,适合指针接收器。因为接收器和参数传递不进行复制,只传递指针

go语言其他类型添加方法

1,概览

1,前文说过,go语言几乎所有类型都可以添加方法。
2,给一种类型添加方法就像给结构体添加方法一样,因为结构体也是一种类型。

2,远离

1,go语言中,使用type关键字,可以定义出任何自定义类型。然后就可以给自定义类型添加方法了

2,实例

type MyInt int

func (m MyInt) IsZero() bool {
    return m == 0
}

func (m MyInt) Add(other int) int {
    return other + int(m)
}

func main(){
    var b MyInt
    fmt.Println(b.IsZero())
    b = 1
    fmt.Println(b.Add(2))
}

Go语言类型内嵌和结构体内嵌

1,概览:

1,结构体可以包含一个或者多个匿名(内嵌)字段。此时类型名就是字段名。
2,go语言的继承是通过内嵌或组合来实现。内嵌就是包含的结构体层层嵌,组合就是包含的结构体并列排
3,go语言结构体内嵌实现的继承是多继承。比如php,java是单继承
4,结构体内嵌初始化,可以把内嵌的类型作为字段名称一样,像普通结构体一样进行初始化
5,内嵌匿名结构体,好处就是结构体定义不会被外部引用到
6,内嵌,组合结构体,不同结构体的成员变量名称尽量不要相同,如果组合有重名的话,层层访问可以访问,直接访问会报错。

2,实例

type T struct{
    Tp1 int
    Tp2 int
}

type S struct{
    Sp1 int
    Sp2 int
    int
    T   //内嵌结构体
    R struct {  //内嵌匿名结构体R
        Rp1 int 
    }
}

//初始化结构体.这里只展示了普通结构体初始化,相应的取指针结构体实例化一样的
func initS(){
    sObj = S{
        Sp1:1,
        SP2:2,
        int:3,
        T:T{
            Tp1:4,
            Tp2:5
        },
        R:struct{
            Rp1 int
        }{
            Rp1:6
        },
    }

}

//结构体嵌套调用
func main(){
    sObj := &S{}
    Sobj.Sp1 = 1
    Sobj.Sp2 = 2
    Sobj.Tp1 = 3
    Sobj.Tp2 = 4
    Sobj.int = 5
}

//如上实例,结构体可以直接访问内嵌结构体的成员

3,内嵌结构体特性

1,内嵌结构体可以直接访问其成员变量,内嵌结构体也可以层层访问其成员变量,两种成员变量访问方式。
2,如果组合有重名的话,层层访问可以访问,直接访问会报错
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值