• 10 结构


    结构

    1. Go 中的struct与C中的struct非常类似,并且Go没有class
    2. 使用Type(Name) struct{}定义结构,名称遵循可见性规则
    3. 支持指向自身的指针类型成员
    4. 支持匿名结构,可用作成员或者定义成员变量
    5. 匿名结构也可以用于map的值
    6. 可以使用字面值对结构进行初始化
    7. 允许直接通过指针来读写结构成员
    8. 相同类型的成员可以直接拷贝赋值
    9. 支持== 与 != 比较运算符,但不支持>或<
    10. 支持匿名字段,本质是定义了以某个类型名为名称的字段
    11. 嵌入结构作为匿名字段看起来像继承,但不是继承
    12. 可以使用匿名字段指针

    struct的简单使用

    我们先定义一个struct,然后在main函数里面使用它即可

    type test struct {
    	Name string
    	Age  int
    }
    
    func main() {
    	a := test{}
    	a.Name = "Leo"  // 对Name这个进行赋值
    	a.Age = 22   // 对Age这个变量进行赋值
    	a := test{   // 也可以这样进行简单初始化,初始化的格式如下:
    		Name: "Leo ",    // 变量名:  值, 
    	}
    	fmt.Println(a)
    }
    
    struct 多层嵌套

    所谓的多层嵌套就是struct里面再包含了一个struct,代码如下所示:

    type person struct {
    	Name    string
    	Age     int
    	contact struct {  // struct里面再包含了一个struct
    		Phone, City string
    	}
    }
    
    func main() {
    	a := person{Name: "joe", Age: 19}
    	a.contact.Phone = "182165234545"  // 给里面那层struct赋值的时候只能这样做
    	a.contact.City = "Beijing"
    	fmt.Println(a)
    }
    
    struct 内存地址的拷贝
    package main
    
    import (
    	"fmt"
    )
    
    type test struct {
    	Name string
    	Age  int
    }
    
    func main() {
    	a := test{
    		Name: "Leo ",
    	}
    	a.Age = 22
    	A(a)
    	fmt.Println(a)  // 此时打印出来的结果还是22
    }
    
    func A(per test) {
    	per.Age = 19
    	fmt.Println("A", per)
    }
    // 打印结果如下:
    A {Leo  19}   // 值已经发生改变
    {Leo  22} // 值没有发生改变
    

    从上面的例子能够看出来,这个函数A的修改并没有影响main方法里面的值,所以可以得出这个修改实际上是test的一个内存拷贝,如果真正想在A里面修改值后影响到 main里面的值,就需要把内存地址传给A,那么就应该这么做,代码如下:

    func main() {
    	a := test{
    		Name: "Leo ",
    	}
    	a.Age = 22
    	A(&a)  // 加上&符合把内存地址传入
    	fmt.Println(a)
    }
    
    func A(per *test) {  // 加上一个*号在test之前
    	per.Age = 19
    	fmt.Println("A", per)
    }
    

    那么问题来了,如果我有多个方法需要传入内存地址,那么该如何一次性让a等于内存地址呢?请看下面的代码

    func main() {
    	a := &test{   // 提前把&放入到test之前
    		Name: "Leo ",
    	}
    	a.Age = 22
    	A(a)
    	B(a)
    	fmt.Println(a)
    }
    
    func A(per *test) {  // 每个方法 的test前面添加一个*即可
    	per.Age = 19
    	fmt.Println("A", per)
    }
    
    func B(per *test) {  // 每个方法 的test前面添加一个*即可
    	per.Age = 90
    	fmt.Println("B", per)
    }
    

    struct 匿名结构

    匿名结构 的写法和js的自执行函数差不多,go的写法是 struct{}{}

    func main() {
    	a := struct {
    		Name string
    		Age  int
    	}{
    		Name: "joe",
    		Age:  19,
    	}
    	fmt.Println(a)
    }
    

    匿名结构

    struct里面没有写变量名,只写了类型,所以赋值的时候只能照着顺序来

    type person struct {
    	string
    	int
    }
    func main() {
    	a := person{"joe", 19}
    	fmt.Println(a)
    }
    

    struct 比较

    两个struct之间比较的话,struct名字必须一样,如下所示

    func main() {
    	a := person{"joe", 19}
    	b := person{"joe", 22}
    	fmt.Println(a == b)  // 两个struct的名字一样才行
    }
    

    在struct继承情况下,如果有同名的变量会发生什么情况

    话不多说,直接看代码:

    import (
    	"fmt"
    )
    
    type human struct {
    	student
    	Name string
    }
    
    type student struct {
    	Name string
    }
    
    func main() {
    	b := human{Name: "hehe", student: student{Name: "Leo"}} // 变量同名了
    	fmt.Println(b.Name, b.student.Name)
    }
    // 打印结果
    hehe Leo
    

    由打印结果为导向,可以看出来,即使在继承struct的情况,有同名的也不会互相影响。

    在struct继承情况下,父类没有的变量名而子类有会发生什么情况

    话不多说,请看代码

    import (
    	"fmt"
    )
    
    type human struct {
    	student
    }
    
    type student struct {
    	Name string
    }
    
    func main() {
    	b := human{student{Name: "Leo"}}
    	fmt.Println(b.Name, b.student.Name)
    }
    // 打印结果
    Leo Leo
    

    由打印结果为导向,可以看出来,如果父struct没有name的话,那么就会从子struct上取值

  • 相关阅读:
    JavaScript中判断函数是new还是()调用
    IE6/7 and IE8/9(Q)中td的上下padding失效
    JQuery中html()方法使用不当带来的陷阱
    有name为action的表单元素时取form的属性action杯具了
    为非IE浏览器添加mouseenter,mouseleave事件
    各浏览器中querySelector和querySelectorAll的实现差异
    仅IE6/7/8中innerHTML返回值忽略英文空格
    各浏览器关键字/保留字作为对象属性的差异
    各浏览器中鼠标按键值的差异
    给body标签和document.body都添加点击事件后仅Firefox弹出了两次
  • 原文地址:https://www.cnblogs.com/liaojiafa/p/6828258.html
Copyright © 2020-2023  润新知