Go语言学习笔记-结构体(Struct)

Go语言结构体


1、概念
结构体是一种聚合的数据类型,是由零个或多个任意类型的值聚合成的实体。
每个值称为结构体的成员。
Go 语言中数组可以存储同一类型的数据,但在结构体中我们可以为不同项定义不同的数据类型。
结构体是由一系列具有相同类型或不同类型的数据构成的数据集合。
组成结构体类型的那些数据称为 字段(fields)。每个字段都有一个类型和一个名字;
在一个结构体中,字段名字必须是唯一的。

2、特点
结构体的概念在软件工程上旧的术语叫 ADT(抽象数据类型:Abstract Data Type),
在一些老的编程语言中叫 记录(Record),比如 Cobol,在 C 家族的编程语言中它也存在,
并且名字也是 struct,在面向对象的编程语言中,跟一个无方法的轻量级类一样。

3、定义结构体
type identifier struct {
    field1 type1
    field2 type2
    ...
}


4、一个非常简单的例子:

 

 

5、访问结构体成员
如果要访问结构体成员,需要使用点号 . 操作符,格式为:结构体.成员名"

 

 

6、初始化结构体
1)、使用 new
使用 new 函数给一个新的结构体变量分配内存,它返回指向已分配内存的指针:
var t *T = new(T),如果需要可以把这条语句放在不同的行
(比如定义是包范围的,但是分配却没有必要在开始就做)。
var t *T t = new(T)
写这条语句的惯用方法是:t := new(T),变量 t 是一个指向 T的指针,
此时结构体字段的值是它们所属类型的零值。
声明 var t T 也会给 t 分配内存,并零值化内存,但是这个时候 t 是类型T。
在这两种方式中,t 通常被称做类型 T 的一个实例(instance)或对象(Object)。

2)、初始化一个结构体实例(一个结构体字面量:struct-literal)的更简短和惯用的方式如下:
ms := &struct1{10, 15.5, "Chris"} // 此时ms的类型是 *struct1

3)、常规初始化
 var ms struct1 ms := struct1{10, 15.5, "Chris"}

7、结构体指针
你可以定义指向结构体的指针类似于其他指针变量,格式如下:
var struct_pointer *Books
以上定义的指针变量可以存储结构体变量的地址。查看结构体变量地址,
可以将 & 符号放置于结构体变量前:
struct_pointer = &Book1
使用结构体指针访问结构体成员,使用 "." 操作符:struct_pointer.title

 

 

8、使用工厂方法创建结构体实例

结构体工厂
Go 语言不支持面向对象编程语言中那样的构造子方法,
但是可以很容易的在 Go 中实现 “构造子工厂“ 方法。
为了方便通常会为类型定义一个工厂,按惯例,工厂的名字以 new 或 New 开头。
假设定义了如下的 File 结构体类型:

type File struct {
    fd      int     // 文件描述符
    name    string  // 文件名
}

下面是这个结构体类型对应的工厂方法,
它返回一个指向结构体实例的指针:

 

func NewFile(fd int, name string) *File {
    if fd < 0 {
        return nil
    }
    return &File(fd, name)
}

然后这样调用它:
f := NewFile(10, "./test.txt")

1、在 Go 语言中常常像上面这样在工厂方法里使用初始化来简便的实现构造子。

2、如果 File 是一个结构体类型,那么表达式 new(File) 和 &File{} 是等价的。

3、这可以和大多数面向对象编程语言中笨拙的初始化方式做个比较:File f = new File(...)。

4、我们可以说是工厂实例化了类型的一个对象,就像在基于类的OO语言中那样。

5、如果想知道结构体类型T的一个实例占用了多少内存,可以使用:size := unsafe.Sizeof(T{})。

8、结构体嵌入和匿名成员
考虑一个二维的绘图程序,提供了一个各种图形的库,例如矩形、
椭圆形、星形和轮形等几何形状。这里是其中两个的定义:
type Circle struct {
    X, Y, Radius int
}

type Wheel struct {
    X, Y, Radius, Spokes int
}
一个Circle代表的圆形类型包含了标准圆心的X和Y坐标信息,和一个Radius表示的半径信息。
一个Wheel轮形除了包含Circle类型所有的全部成员外,还增加了Spokes表示径向辐条的数量。
我们可以这样创建一个wheel变量:

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


随着库中几何形状数量的增多,我们一定会注意到它们之间的相似和重复之处,
所以我们可能为了便于维护而将相同的属性独立出来:

 

 

 

结构体字面值必须遵循形状类型声明时的结构,
所以我们只能用下面的两种语法,它们彼此是等价的:
这样改动之后结构体类型变的清晰了,但是这种修改同时也导致了访问每个成员变得繁琐:
var w Wheel w.Circle.Center.X = 8 w.Circle.Center.Y = 8 w.Circle.Radius = 5 w.Spokes = 20
结构体字面值必须遵循形状类型声明时的结构,所以我们只能用下面的两种语法,它们彼此是等价的:

 

 好的,谢谢大家今天就分享到这里  O(∩_∩)O~

 

更多技术分享->            

 

posted @ 2022-07-07 09:24  大熊君Bigbear  阅读(561)  评论(0编辑  收藏  举报