GoLang之结构体

本文详细介绍了Go语言中结构体的使用,包括定义、声明与初始化、值类型与引用数据类型的区别,以及匿名结构体和结构体嵌套的概念。通过实例展示了结构体的创建、赋值以及指针的使用,帮助读者深入理解Go语言中的结构体操作。
摘要由CSDN通过智能技术生成

GoLang结构体

基本使用

首先,给出结构体的一些理解。

结构体是一些属性的集合,这些属性可以称作为字段,在程序中其实就是一些变量。通过这些属性(字段)的组合来描述某一事物的特征。实际上,结构体就是对所要描述物质的抽象。

1. 定义结构体

type struct_name struct{
    var_name1 type
    var_name2 type
    var_name3 type
    .
    .
    .
    var_namen type
}

2. 声明并初始化结构体对象

结构体示例:

type Animal struct{
    name string
    age int
    sex boolean
}
  • 方法一:声明结构体变量,然后通过.运算符访问赋值,进行初始化
var st1 Animal
st1.name = "猫"
st1.age = 3
st1. sex = false
println(st1.name)
println(st1.age)
println(st1.sex)
//结果为:
//猫
//3
//false
  • 方法二:声明的同时使用{}进行初始化
var st1 Animal = Animal{
    name: "猫",
    age: 3,
    sex: false,    //这里最后一个逗号不能省略,如果要省略,那么右大括号应该位于这一行
}
//或者简写为如下形式
st2 := Animal{
    name: "猫",
    age: 3,
    sex: false,
}
//或者简写为如下形式
st3 := Animal{  //使用这种形式时,赋值顺序与结构体中变量的声明顺序一致。
    "猫",
    3,
    false,
}
  • 方法三:使用new()函数:专门用来创建某种类型的指针的函数
st4 := new(Animal)
st4.name = "猫"
st4.age = 3
st4.sex = false
fmt.Printf("%p---%T", st4, st4)
//结果为:
//0xc0000593c0---*main.Person

从返回结果*main.Person可以看出,使用new()函数创建的结构体示例,返回的是一个结构体指针,它指向使用new()函数开辟的空间。

同时,对于结构体指针,可以通过.运算符直接访问其指向结构体的字段。

3. 值类型与引用数据类型

Golang语言中:

值类型:int, float, bool, string, array, struct

引用类型: slice, map ,function, pointer

  • 针对于struct,其实例为值类型。当将一个结构体变量赋值给另外一个结构体变量时,会发生一次拷贝。比如:st1 := st2,这里st2事先已经初始化,那么会将st2的值复制一份,然后放到st1的内存空间中去。

示例:

var st2 Animal = Animal{
    name: "猫",
    age: 3,
    sex: false,
}
st1 := st2
st1.name = "狗"
fmt.Println(st1)
fmt.Println(st2)
//结果为:
//{狗 3 false}
//{猫 3 false}

从上面这段代码可以看出,修改st1并不会影响st2的值。

示例:

var st2 *Animal = new(Animal)
st2.name = "猫"
st2.age = 3
st2.sex =false

st1 := st2
st1.name = "狗"
fmt.Println(st1)
fmt.Println(st2)
//结果为:
//&{狗 3 false}
//&{狗 3 false}
//0xc0000503c0---0xc0000503c0

可见,st1st2都是结构体的引用,都指向同一内存空间。所以通过st1st2修改结构体的字段,都会影响到另一方的值。

匿名结构体及匿名字段

  • 匿名结构体

当我们需要使用一个结构体并声明其变量来使用时有两种做法。一种是先定义该结构体,然后声明其变量;另一种便是使用匿名结构体。使用匿名结构体,不需要使用type关键字指定结构体类型的名称。

使用语法:

struct{
    field1 type
    filed2 type
    .
    .
    .
    filedn type
}{
    field1: value1,
    field2: value2,
    field3: valur3,
    .
    .
    .
    fieldn: valuen,
}

解析:第一个大括号中的内容,是对匿名结构体的字段定义。第二个大括号中的内容是对匿名结构体字段的初始化

使用示例:

animal := struct{
    name string
    age int
}{
    name: "猫",
    age: 3,
}
fmt.Println(animal)
//结果为:
{3}
  • 匿名结构体字段

对于结构体中的字段,有时可以省略其字段名。注:结构体中的变量也可以称其为字段。

示例:

type Animal struct{
    string
    int
}

声明一个Animal的结构体变量:

var a Animal = Animal{"猫", 3}

如何访问没有字段名的结构体的字段呢?这种情况下,字段的类型默认被作为字段名处理。也就是说,字段的类型即起到数据类型的作用,也充当字段名的作用。

示例:

var a Animal = Animal{"猫", 3}
fmt.Println(a.string, a.int)
//结果为:
//猫 3
  • 根据上面所说,可以知道,结构体的匿名字段只有在当前结构体的字段类型不复杂时使用。即当结构体中出现多个同一类型的字段时,匿名字段就无法使用。因为匿名字段的类型充当字段标识符的作用,如果出现相同类型的匿名字段,那么无法确定是对哪个字段的访问。

示例:如下代码段,会让编译器报错

type Animal struct{
    string
    int
    string   //这里有了两个string类型的匿名字段,报错
}

结构体的嵌套

简单来说,结构体的定义中有另外一个结构体的定义,这就是结构体的嵌套。

何时使用呢?一般,当一个结构体的属性中拥有另外一个结构体时就会使用结构体的嵌套。

如下:

type Book struct{  //定义Book结构体,描述书的名称与价格
    name string
    price float64
}

type Student struct{  //定义student结构体,描述学生的姓名,年龄,与读过的书
    name string
    age int
    book Book
}

参考资料

  • https://www.bilibili.com/video/BV1jJ411c7s3?p=86&vd_source=008445eb63b17edad78a03ae3d20c08a
  • https://www.runoob.com/go/go-structures.html
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值