天天看点

Golang从入门到精通(十四):Golang结构体

Golang是一门很特殊的语言,虽然它出生比较晚,但是在很多地方却和现在的编程语言有所不同。现在的编程语言要么是函数式的、要么是面向对象的,而Go语言却有指针、结构体这些概念,并解决了C语言的一些坑。从这个角度上说,Golang可以看做C语言的填坑加强版。

结构体简介

Go 语言通过类型别名(alias types)和结构体的形式支持用户自定义类型,或者叫定制类型。一个带属性的结构体试图表示一个现实世界中的实体。结构体是复合类型(composite types),当需要定义一个类型,它由一系列属性组成,每个属性都有自己的类型和值的时候,就应该使用结构体,它把数据聚集在一起。然后可以访问这些数据,就好像它是一个独立实体的一部分。结构体也是值类型,因此可以通过 new 函数来创建。

组成结构体类型的那些数据称为 字段(fields)。每个字段都有一个类型和一个名字;在一个结构体中,字段名字必须是唯一的。

结构体的概念在软件工程上旧的术语叫 ADT(抽象数据类型:Abstract Data Type)。在 C++ 它也存在,并且名字也是 struct,在面向对象的编程语言中,跟一个无方法的轻量级类一样。因为 Go 语言中没有类的概念,所以在 Go 中结构体有着更为重要的地位。

结构体定义

结构体定义的一般方式如下:

type identifier struct {
    field1 type1
    field2 type2
    ...
}
           

在结构体内部定义它们的成员变量和类型,只是类型要放到后面,并且变量之间不用逗号。

例如:

type Student struct {
    name   string
    age    int
    weight float32
    score  []int
}
           

如果成员变量的类型相同的话,可以把它们写到同一行。所以

type T struct {a, b int}

也是合法的语法,它更适用于简单的结构体。

结构体里的字段都有 名字,像 field1、field2 等,如果字段在代码中从来也不会被用到,那么可以命名它为 _。

结构体初始化

这里有两种方式可以初始化结构体,按原始字段顺序进行初始化和自定义字段顺序进行初始化。

在Go语言里可以直接使用 fmt.Println 打印一个结构体,默认输出可以很好的显示它的内容,类似使用 %v 选项。

就像在面向对象语言所作的那样,可以使用点号符给字段赋值:

structname.fieldname = value

同样的,使用点号符可以获取结构体字段的值:

structname.fieldname

示例代码如下:

package main

import (
    "fmt"
)

type Student struct {
    name   string
    age    int
    weight float32
    score  []int
}

func main() {
    stu01 := Student{"stu01",,, []int,,}}                //按照字段顺序进行初始化
    stu02 := Student{age:, weight:, score: []int,}, name: "stu02"} ///通过 field:value 形式初始化,该方式可以自定义初始化字段的顺序
    stu01.age =
    fmt.Println(stu01.age)
    fmt.Println(stu02)

}
           

结构体new函数

关于结构体和指针的结合我们在下一关重点讲下,这里简单提下它们的组合使用。

一般在进行例如

type T struct {a, b int}

的结构体定义之后

习惯使用

t := new(T)

给该结构体变量分配内存,它返回指向已分配内存的指针。变量

t

是一个指向

T

的指针,此时结构体字段的值是它们所属类型的零值。

声明

var t T

也会给 t 分配内存,并零值化内存,但是这个时候

t

是类型

T

。在这两种方式中,t 通常被称做类型

T

的一个实例

(instance)

或对象

(Object)

var t *T = new(T)

等价于

t := new(T)

一个简单的结构体

new

函数的例子如下:

package main
import "fmt"

type struct1 struct {
    i1  int
    f1  float32
    str string
}

func main() {
    ms := new(struct1)
    ms.i1 =
    ms.f1 =
    ms.str= "Chris"

    fmt.Printf("The int is: %d\n", ms.i1)
    fmt.Printf("The float is: %f\n", ms.f1)
    fmt.Printf("The string is: %s\n", ms.str)
    fmt.Println(ms)
}