zoukankan      html  css  js  c++  java
  • Go

     结构体的介绍
        Golang也支持面向对象编程(OOP),但是和传统的面向对象编程有区别,并不是纯粹的面向对象语言。所以我们说Golang支持面向对象编程特性是比较准确的。
        Golang没有类(class),go语言的结构体(struct)和其他编程语言的类(class)有同等地位,可以理解golang是基于struct来实现OOP特性的;
        Golang面向对象编程非常简洁,去掉了传统OOP语言的继承,方法重载,构造函数和析构函数,隐藏的this指针等;
        Golang任然有面向对象编程的继承,封装和多态的特性,只是实现的方式和其他OOP语言不一样,比如继承,Golang没有extends关键字,继承是通过匿名字段来实现的。
        Golang面向对象(OOP)很优雅,OOP本身就是语言类型系统(type system)的一部分,通过接口(interface)关联,耦合性低,也非常灵活,也就是说在golang中面向接口编程是非常重要的特性;
     
    结构体与结构体变量的区别
            将一类事物的特性提取出来,形成一个新的数据类型,就是一个结构体;
            通过这个结构体,我们可以创建多个变量(实例/对象),事物可以是猫类,也可以是Person,Fish 或者某个工具类...
            从某个结构体到变量,就是创建了一个该结构体变量,也可以说是定义一个该结构体变量;
            结构体:是自定义的数据类型,代表一类事物(猫,人);
            结构体变量【实例】是具体的,实际的,代表一个具体的变量;
     
    结构体在内存中布局
            结构体即值类型,可以直接修改属性,即变量直接指向空间,而不是指向一个地址,而再通过地址指向某空间;
     
    结构体的声明和字段使用陷阱
            type  标识符(结构体名称)  struct {
                    field1  type
                    field2  type
            }
            示例:
            type Student struct {  // 结构体名字首字母大写既可以跨包使用
                Name  string
                Age      int
                Address string
            }
            字段/属性 基本介绍:
                从概念或叫法上看,结构体字段 = 属性 = field 
                字段是结构体的一个组成部分,一般是基本数据类型,数组,也可以是引用类型;
                注意事项和细节说明:
                    在创建一个结构体变量后,如果没有给字段赋值,各字段都对应一个零值(默认值),规则同前面讲的一样:
                    布尔类型是 false,整型:0,字符串是:""
                    数组类型的默认值和它的元素类型相关,比如 score [3]int  则为[0,0,0]
                    指针,slice, 和map的零值都是null即nil,即还没有分配空间,需要先make才能使用。
           示例:
                // 结构体
                type Person struct {     
                        Name string      
                        Age  int      
                        Scores [5]float64     
                        ptr   *int  // 指针     
                        slice []int  // 切片     
                        map1  map[string]string  // map  
                }
                // 实例化一个Person对象
                // 结构体 类似 其他语言的class    
                var p1 Person      
                fmt.Println(p1)  // { 0 [0 0 0 0 0] <nil> [] map[]}     
                if p1.ptr == nil {         
                    fmt.Println("ok1")     
                }     
                if p1.slice == nil {         
                    fmt.Println("ok2")     
                }     
                if p1.map1 == nil {         
                    fmt.Println("ok3")     
                }     
                // 使用slice  一定要 make     
                p1.slice = make([]int, 10)     
                p1.slice[0] = 200     
                fmt.Println(p1.slice)  // [200 0 0 0 0 0 0 0 0 0]     
                // 使用map  一定要make     
                p1.map1 = make(map[string]string)     
                p1.map1["k1"] = "v1"     
                fmt.Println(p1.map1)  // map[k1:v1]     
                // 基本数据类型需要使用 new     
                p1.ptr = new(int)  // new 内置函数对 值类型进行 分配内存 需要传类型参数     
                *p1.ptr = 10     
                fmt.Println(p1.ptr)  // 0xc0000a0838
                fmt.Println(*p1.ptr)  // 10
                fmt.Println(p1)  // { 0 [0 0 0 0 0] 0xc0000a0838 [200 0 0 0 0 0 0 0 0 0] map[k1:v1]}
     
            不同结构体变量的字段是独立的,互不影响,一个结构体变量字段的更改,不影响另外一个。
                    示例:
                        type Monster struct {    
                            Name string     
                            Age  int  
                        }
                        var m1 Monster    
                        m1.Name = "袋鼠"     
                        m1.Age = 200     
     
                        m2 := m1    // 完全复制了一份新的空间,然后把值也赋值给 m2 所以 修改m2 不会影响 m1
                        m2.Name = "花袋鼠"     
                        fmt.Println(m1, m2) // {袋鼠 200} {花袋鼠 200}
     
    创建结构体实例的四种方式:
        创建结构体变量和访问结构体字段
                方式1:直接声明
                    var per Person
                方式2:{}  推荐
                    var per  Person = Person{}
                    示例:
                        m := Monster{"杀无赦", 100}    
                        fmt.Println(m)    // {杀无赦 100}
                方式3:
                    示例:
                        var m1 *Monster = new(Monster)    
                        // 因为m1 是一个指针,因此标准的给字段赋值方式     
                        // (*m1).Name = "老沙" 也可以写成 m1.Name = "沙师弟"     
     
                        // 原因:go的设计者 为了程序员使用方便,底层会对 m1.Name = "沙师弟" 进行处理                           // 会给 m1 加上 取值运算 (*m1).Name = "沙师弟"     
                        (*m1).Name = "老沙"     
                        m1.Name = "沙师弟"     
                        (*m1).Age = 200     
                        m1.Age = 300     
                        fmt.Println(m1)  // &{沙师弟 300}     
                        fmt.Println(*m1)  // {沙师弟 300}
                方式4:类似方式三 都是结构体指针
                    示例:
                        // var p *Person = &Person{"smith", 30}   也可以赋初值
                        var p *Person = &Person{}    
                        p.Name = "mary"     
                        p.Age = 30     
                        fmt.Println(*p)  // {mary 30 }
     
    结构体使用细节
           结构体的所有字段在内存中是连续的;
            结构体是用户单独定义的类型,和其它类型进行转换时需要有完全相同的字段(名字,,个数,和类型)
           示例:
                type A struct {        
                        num int      
                }     
                type B struct {         
                        num int      
                }     
                var a A      
                var b B      
                a = A(b)   // 可以转换,前提:结构体的字段完全一样;
     
            结构体进行type重新定义(相当于取别名),Golang认为是新的数据类型,但是相互间可以强转。
            struct的每个字段上,可以写上一个tag(Domain  string `json:"domain"` -->tag),该tag可以通过反射机制获取,常见的使用场景就是序列化和反序列化;(结构体的序列化:使用的包:"encoding/json" , 方法:json.Marshal(结构体实例),返回的是[]byte 切片,所以需要强转为str--> string([]byte) ---> 变为字符串)
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
  • 相关阅读:
    C++中函数模板template的使用
    C++中模板template和类class的结合使用
    Python中shuffle函数
    Python中利用tkinter模块构建图形用户界面GUI
    Python中怎样初始化一个类类class?
    Python中字典的has_key方法在3.4版本中改为in
    Python中怎样对数据集整体进行映射转换类型
    matlab中怎样对矩阵的某一列进行排序而使得其他列对应移动??
    Python中怎样使用shape计算矩阵的行和列
    27.反射2.md
  • 原文地址:https://www.cnblogs.com/guo-s/p/14027140.html
Copyright © 2011-2022 走看看