美文网首页
第六章 结构体

第六章 结构体

作者: Benedict清水 | 来源:发表于2021-02-20 17:38 被阅读0次

Go语言中结构体是带有成员的复合类型。结构体成员是由一系列成员变量构成,这些成员变量也被称为“字段”。字段有以下特性:

  • 字段拥自己的类型和值
  • 字段名必须唯一
  • 字段的类型也可以是结构体,甚至是字段所在结构体的类型

6.1 定义结构体

结构体的定义格式如下:

type 类型名 struct {
    字段1 类型
    字段2 类型
    ...
}
  • 类型名:标识自定义结构体的名称,在同一个包内不能重复。
  • struct{}:表示结构体类型,type 类型名 struct{}可以理解为将struct{}结构体定义为类型名的类型。
  • 字段1、字段2......:表示结构体字段名。结构体中的字段名必须唯一。

示例如下:

type Point struct{
    x int
    y int
}

6.2 实例化结构体——为结构体分配内存并初始化

实例化就是根据结构体定义的格式创建一份与格式一致的内存区域,结构体实例与实例间的内存是完全独立的。

6.2.1 基本的实例化形式

结构体本身是一种类型,以var的方式声明结构体即可完成实例化。
基本的实例化格式如下:

var ins T
  • T为结构体类型。
  • ins为结构体的实例。
    示例如下:
type Point struct{
    x int
    y int
}
var p Point
p.x = 10
p.y = 20

使用“.”来访问结构体的成员变量,如p.x和p.y等。结构体成员变量的赋值方法与普通变量的一致。

6.2.2 创建指针类型的结构体

Go语言中,还可以使用new关键字对类型(包括结构体、整型、浮点数、字符串等)进行实例化,结构体在实例化后会形成指针类型的结构体。
使用new的格式如下:
ins := new(T)

  • T 为类型,可以是结构体、整型、字符串等
  • ins: T 类型被实例化后保存到ins变量中,ins的类型为*T,属于指针。

Go 语言让我们可以像访问普通结构体一样使用“.”访问结构体指针的成员。
下面的例子定义了一个玩家(Player)的结构,玩家拥有名字、生命值和魔法值,实例化玩家(Player)结构体后,可对成员进行赋值。

type Player struct{
    Name string
    HealthPoint int
    MagicPoint int
}
tank := new(Player)
tank.Name = "Canon"
tank.HealTPoint = 300

经过new实例化的结构体实例在成员赋值上与基本实例化的写法一致。

6.2.3 取结构体的地址实例化

在Go语言中,对结构体进行“&”取地址操作时,视为对该类型进行一次new的实例化操作。取地址格式如下:

ins := &T{}
  • T 表示结构体类型。
  • ins 为结构体的实例,类型为*T,是指针类型。

下面使用结构体定义一个命令行指令,指令中包含名称、变量关联和注释等。对Command进行指针地址的实例化,并完成赋值过程。代码如下:

type Command struct{
    Name string
    Var *int
    Comment string
}
// 对结构体进行赋值
var version int = 1
cmd := &Command()
cmd.Name = "version"
cmd.Var = &version
cmd,Comment = "show version"

取地址实例化是最广泛的一种结构体实例化方式。

6.3 初始化结构体的成员变量

初始化有两种方式:一种是字段“键值对”形式,另一种是多个值的列表形式。

6.3.1 使用“键值对”初始化结构体

结构体实例化后字段的默认值是字段类型的默认值,数值为0,字符串为空字符串,布尔为false,指针为nil等。

1. 键值对初始化的格式如下:
ins := 结构体类型名{
    字段1: 值,
    字段2: 值,
    ...
}
  • 键值之间以“:”分隔;键值对之间以“,”分隔。
2. 使用键值对填充结构体的例子
type People struct {
    name string
    child *People
}

relation := &People{
    name:"爷爷",
    child: &People{
        name: "爸爸",
        child: &People{
            name: "我",
        },
    },
}

6.3.2 使用多个值得列表初始化结构体

1. 多个值列表初始化结构体的书写格式

多个值使用逗号分隔初始化结构体,例如:

ins := 结构体类型名{
    字段1的值,
    字段2的值,
    ···
}
  • 必须初始化结构体的所有字段。
  • 每一个初始值的填充顺序必须与字段在结构体中的声明顺序一致。
  • 键值对与值列表的初始化形式不能混用。
2. 多个值列表初始化结构体的例子
package main

import "fmt"

type Address struct {
    Province string
    City string
    ZipCode int
    PhoneNumber string
}


func main()  {
    addr := Address {
        "四川",
        "成都",
        610000,
        "15678903479",
    }
    fmt.Println(addr)
}

输出结果:

{四川 成都 610000 15678903479}

6.3.3 初始化匿名结构体

匿名结构体没有类型名称,无须通过type关键字定义就可以直接使用。

1. 匿名结构体定义格式和初始化写法

匿名结构体的初始化写法由结构体定义和键值对初始化两部分组成。结构体定义时没有结构体类型名,只有字段和类型定义。

ins := struct{
        字段1 字段类型
        字段2 字段类型
        ...
    }{
        初始化字段1:值,
        初始化字段2:值,
        ...
    }
2. 使用匿名结构体的例子
package main

import "fmt"

// 打印消息类型,传入匿名结构体
func printMsgType(msg *struct{
    id int
    data string
})  {
    fmt.Printf("%T\n", msg)
    fmt.Println(msg)
}

func main()  {
    msg := &struct {
        id int
        data string
    }{
        1024,
        "hello",
    }
    printMsgType(msg)
}

输出结果:

*struct { id int; data string }
&{1024 hello}

匿名结构体在使用时需要重新定义,造成大量的重复代码,因此开发中较少使用。

6.4 构造函数——结构体和类型的一系列初始化操作的函数封装

Go语言没有提供构造函数的功能。结构体的初始化过程可以使用函数封装实现。

6.4.1 模拟构造函数重载

使用结构体描述一只猫。

package main

import "fmt"

type Cat struct {
    Color string
    Name string
}

func NewCatByName(name string) *Cat {
    return &Cat{
        Name: name,
    }
}

func NewCatByColor(color string) *Cat {
    return &Cat{
        Color: color,
    }
}

func main()  {
    var cat1, cat2 *Cat
    cat1 = NewCatByName("san")
    cat2 = NewCatByColor("Black")
    fmt.Println(cat1, cat2)
}

6.4.2 带有父子关系的结构体的构造和初始化——模拟父级构造调用

使用结构体描述猫和黑猫的关系时,将猫(Cat)的结构体嵌入黑猫(BlackCat)中,表示黑猫拥有猫的特性,然后再使用不同的构造函数分别构造出黑猫和猫两个结构体实例。

package main

import "fmt"

type Cat struct {
    Color string
    Name string
}

type BlackCat struct {
    Cat  //嵌入Cat,类似于派生
}

// "构造基类"
func NewCat(name, color string) *Cat {
    return &Cat{
        Name: name,
        Color: color,
    }
}

// "构造子类"
func NewBlackCat(name, color string) *BlackCat  {
    cat := &BlackCat{}
    cat.Color = color
    cat.Name = name
    return cat
}

func main()  {
    cat := NewCat("san","write")
    blackCat := NewBlackCat("san","black")
    fmt.Println(cat, blackCat)
}

相关文章

  • 第六章 结构体

    Go语言中结构体是带有成员的复合类型。结构体成员是由一系列成员变量构成,这些成员变量也被称为“字段”。字段有以下特...

  • 结构体

    [toc] 结构体的定义方式 先定义结构体类型,再定义结构体变量 定义结构体类型的同时定义结构体变量 定义结构体类...

  • 【C语言笔记】<十九>结构体

    结构体的基本概念 结构体初始化 结构体的内存存储细节 结构体定义的方式 结构体类型的作用域 指向结构体的指针 结构...

  • C结构体和链表

    一,结构体变量定义及初始化 二,无名结构体 备注:无名结构体很少使用 三,宏定义结构体 四,结构体嵌套 五,结构体...

  • 结构体

    结构体定义* 结构体中的格式:* struch 结构体名* {* 结构体成员变量* }* 结构体中的特点* 1.结...

  • 结构体数组的定义

    结构体数组的定义 1、先定义结构体类型,再定义结构体数组 2、定义结构体类型的同时定义结构体数组 3、省略结构体类...

  • C#结构体,析构方法,跨程序访问

    结构体 结构体定义 结构体的语法格式: struct + 结构体名 { 结构体成员变量(相当于类中的字段) } 结...

  • <>

    第六章重点: go语言数据类型:基础类型(数字,字符串,布尔类型),复合类型(数组,结构体),引用类型(指针,切片...

  • 结构体

    结构体有名定义 无名定义 结构体嵌套定义 结构体内存对齐 结构体成员初始化 结构体变量引用 结构体的有名定义:直白...

  • 菜鸡学Swift3.0 13.结构体

    结构体 struct 是值类型 1.定义结构体 struct 结构体类型 { var 结构体属性:类型 ...} ...

网友评论

      本文标题:第六章 结构体

      本文链接:https://www.haomeiwen.com/subject/phdxfltx.html