• go语言结构体


    定义:

    是一种聚合的数据类型,是由零个或多个任意类型的值聚合成的实体。

    成员:

    每个值称为结构体的成员。

    示例:

    用结构体的经典案例处理公司的员工信息,每个员工信息包含一个唯一的员工编号、员工的名字、家庭住址、出生日期、工作岗位、薪资、上级领导等等。所有的这些信息都需要绑定到一个实体中,可以作为一个整体单元被复制,作为函数的参数或返回值,或者是被存储到数组中,等等。

    定义结构体:

    type Employee struct {
        ID        int
        Name      string
        Address   string
        DoB       time.Time
        Position  string
        Salary    int
        ManagerID int
    }

    定义变量:

    var dilbert Employee

    访问成员:

    dilbert.Salary -= 5000

    取成员地址:

    position := &dilbert.Position
    *position = "Senior " + *position
    点操作符与指向结构体的指针:
    var employeeOfTheMonth *Employee = &dilbert
    employeeOfTheMonth.Position += " (proactive team player)"

    成员定义顺序:

    通常一行对应一个结构体成员,成员的名字在前类型在后,不过如果相邻的成员类型如果相同的话可以被合并到一行,就像下面的Name和Address成员那样

    type Employee struct {
        ID            int
        Name, Address string
        DoB           time.Time
        Position      string
        Salary        int
        ManagerID     int
    }

    成员命名规则:

    如果结构体成员名字是以大写字母开头的,那么该成员就是导出的;这是Go语言导出规则决定的。一个结构体可能同时包含导出和未导出的成员。

    导出含义:在其他包中可进行读写。

    一个命名为S的结构体类型将不能再包含S类型的成员:因为一个聚合的值不能包含它自身。(该限制同样适应于数组。)但是S类型的结构体可以包含*S指针类型的成员,这可以让我们创建递归的数据结构,比如链表和树结构等。

    type tree struct {
        value       int
        left, right *tree
    }

    结构体面值:

    可以指定每个成员的值。

    type Point struct{ X, Y int }
    
    p := Point{1, 2}
    上面的是第一种写法,要求以结构体成员定义的顺序为每个结构体成员指定一个面值。还可以:
    anim := gif.GIF{LoopCount: nframes}

    以成员名字和相应的值来初始化,可以包含部分或全部的成员;在这种形式的结构体面值写法中,如果成员被忽略的话将默认用零值。因为,提供了成员的名字,所有成员出现的顺序并不重要。

    注意:两种不同形式的写法不能混合使用。

    结构体嵌入和匿名成员:
    type Point struct {
        X, Y int
    }
    
    type Circle struct {
        Center Point
        Radius int
    }
    
    type Wheel struct {
        Circle Circle
        Spokes int
    }

    访问每个成员:

    var w Wheel
    w.Circle.Center.X = 8
    w.Circle.Center.Y = 8
    w.Circle.Radius = 5
    w.Spokes = 20

    在次简化结构体定义:

    type Circle struct {
        Point
        Radius int
    }
    
    type Wheel struct {
        Circle
        Spokes int
    }

    得意于匿名嵌入的特性,我们可以直接访问叶子属性而不需要给出完整的路径:

    var w Wheel
    w.X = 8            // equivalent to w.Circle.Point.X = 8
    w.Y = 8            // equivalent to w.Circle.Point.Y = 8
    w.Radius = 5       // equivalent to w.Circle.Radius = 5
    w.Spokes = 20

    结构体字面值必须遵循形状类型声明时的结构,所以只能用下面的两种语法,它们彼此是等价的:

    w = Wheel{Circle{Point{8, 8}, 5}, 20}
    
    w = Wheel{
        Circle: Circle{
            Point:  Point{X: 8, Y: 8},
            Radius: 5,
        },
        Spokes: 20, // NOTE: trailing comma necessary here (and at Radius)
    }

    结构体tag:

    在结构体声明中,Year和Color成员后面的字符串面值是结构体成员Tag

    type Movie struct {
        Title  string
        Year   int  `json:"released"`
        Color  bool `json:"color,omitempty"`
        Actors []string
    }
    
    var movies = []Movie{
        {Title: "Casablanca", Year: 1942, Color: false,
            Actors: []string{"Humphrey Bogart", "Ingrid Bergman"}},
        {Title: "Cool Hand Luke", Year: 1967, Color: true,
            Actors: []string{"Paul Newman"}},
        {Title: "Bullitt", Year: 1968, Color: true,
            Actors: []string{"Steve McQueen", "Jacqueline Bisset"}},
        // ...
    }

    这样的数据结构特别适合JSON格式,并且在两种之间相互转换也很容易。将一个Go语言中类似movies的结构体slice转为JSON的过程叫编组(marshaling)。编组通过调用json.Marshal函数完成:

    data, err := json.Marshal(movies)
    if err != nil {
        log.Fatalf("JSON marshaling failed: %s", err)
    }
    fmt.Printf("%s
    ", data)

    Marshal函数返还一个编码后的字节slice,包含很长的字符串,并且没有空白缩进;我们将它折行以便于显示:

    [{"Title":"Casablanca","released":1942,"Actors":["Humphrey Bogart","Ingr
    id Bergman"]},{"Title":"Cool Hand Luke","released":1967,"color":true,"Ac
    tors":["Paul Newman"]},{"Title":"Bullitt","released":1968,"color":true,"
    Actors":["Steve McQueen","Jacqueline Bisset"]}]
    其中Year名字的成员在编码后变成了released,还有Color成员编码后变成了小写字母开头的color。这是因为构体成员Tag所导致的。一个构体成员Tag是和在编译阶段关联到该成员的元信息字符串:
    Year  int  `json:"released"`
    Color bool `json:"color,omitempty"`

    结构体的成员Tag可以是任意的字符串面值,但是通常是一系列用空格分隔的key:"value"键值对序列;因为值中含义双引号字符,因此成员Tag一般用原生字符串面值的形式书写。

  • 相关阅读:
    (9)ASP.NET Core2.2 中的MVC路由二
    (8)ASP.NET Core2.2 中的MVC路由一
    (7)ASP.NET Core2.2 中的错误处理
    (6)ASP.NET Core2.2 中使用IHttpClientFactory发出HTTP请求
    (5)ASP.NET Core2.2 中的静态文件
    (4)ASP.NET Core2.2 中间件
    蒲公英 · JELLY技术周刊 Vol.05: Rust & Electron 的高性能实践 -- Finda
    Taro 2.2 全面插件化,支持拓展和定制个性化功能
    使用 Taro 快速开发京东小程序
    技术周刊 · 0202 年了,你还不学一下 WASM 么?
  • 原文地址:https://www.cnblogs.com/zsy/p/5450166.html
Copyright © 2020-2023  润新知