go结构体初始化_Go语言结构体与初始化图文详解

Go 通过类型别名(alias types)和结构体的形式支持用户自定义类型。

结构体是复合类型,当需要定义类型,它由一系列属性组成,每个属性都有自己的类型和值的时候,就应该使用结构体,它把数据聚集在一起。

结构体也是值类型,因此可以通过 new 函数来创建

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

一,结构体定义

结构体定义的一般方式如下:type identifier struct {

field type1

field type2}

type T struct {a, b int} 也是合法的语法,它更适用于简单的结构体

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

结构体类型和字段的命名遵循可见性规则,所以可能存在一个结构体类型的某些字段是导出的,而另一些没有导出。

结构体的字段可以是任何类型,甚至是结构体本身,也可以是函数或者接口。可以声明结构体类型的一个变量,然后像下面这样给它的字段赋值:var s T

s.a = 5

s.b = 8

数组也可以看作是一种结构体类型,不过它使用下标而不是具名的字段

二,初始化

方式一:通过 var 声明结构体

在 Go 语言中当一个变量被声明的时候,系统会自动初始化它的默认值,比如 int 被初始化为 0,指针为 nil。

var 声明同样也会为结构体类型的数据分配内存,所以我们才能像上一段代码中那样,在声明了 var s T 之后就能直接给他的字段进行赋值

方式二:使用 new

使用 new 函数给一个新的结构体变量分配内存,它返回指向已分配内存的指针:var t *T = new(T)。type struct1 struct {

i1 int

f1 float32

str string}func main() {

ms := new(struct1)

ms.i1 = 10

ms.f1 = 15.5

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)

}

与面向对象语言相同,使用点操作符可以给字段赋值:structname.fieldname = value。

同样的,使用点操作符可以获取结构体字段的值:structname.fieldname。

方式三:使用字面量type Person struct {

name string

age int

address string

}

func main() {

var p1 Person

p1 = Person{"lisi", 30, "shanghai"} //方式A

p2 := Person{address:"beijing", age:25, name:"wangwu"} //方式B

p3 := Person{address:"NewYork"} //方式C

}

在(方式A)中,值必须以字段在结构体定义时的顺序给出。(方式B)是在值前面加上了字段名和冒号,这种方式下值的顺序不必一致,并且某些字段还可以被忽略掉,就想(方式C)那样。

除了上面这三种方式外,还有一种初始化结构体实体更简短和常用的方式,如下:ms := &Person{"name", 20, "bj"}

ms2 := &Person{name:"zhangsan"}

&Person{a, b, c} 是一种简写,底层仍会调用 new(),这里值的顺序必须按照字段顺序来写,同样它也可以使用在值前面加上字段名和冒号的写法(见上文的方式B,C)。

表达式 new(Type) 和 &Type{} 是等价的。

三,几种初始化方式之间的区别

到目前为止,我们已经了解了三种初始化结构体的方式://第一种,在Go语言中,可以直接以 var 的方式声明结构体即可完成实例化

var t T

t.a = 1

t.b = 2

//第二种,使用 new() 实例化

t := new(T)

//第三种,使用字面量初始化

t := T{a, b}

t := &T{} //等效于 new(T)

使用 var t T 会给 t 分配内存,并零值化内存,但是这个时候的 t 的类型是 T

使用 new 关键字时 t := new(T),变量 t 则是一个指向 T 的指针

从内存布局上来看,我们就能看出这三种初始化方式的区别:

使用 var 声明:

使用 new 初始化:

使用结构体字面量初始化:

下面来看一个具体的例子:package main

import "fmt"

type Person struct {

name string

age int

}

func main() {

var p1 Person

p1.name = "zhangsan"

p1.age = 18

fmt.Printf("This is %s, %d years old\n", p1.name, p1.age)

p2 := new(Person)

p2.name = "lisi"

p2.age = 20

(*p2).age = 23 //这种写法也是合法的

fmt.Printf("This is %s, %d years old\n", p2.name, p2.age)

p3 := Person{"wangwu", 25}

fmt.Printf("This is %s, %d years old\n", p3.name, p3.age)

}

输出:This is zhangsan, 18 years old

This is lisi, 23 years old

This is wangwu, 25 years old

上面例子的第二种情况,虽然 p2 是指针类型,但我们仍然可以像 p2.age = 23 这样赋值,不需要像 C++ 中那样使用 -> 操作符,Go 会自动进行转换。

注意也可以先通过 * 操作符来获取指针所指向的内容,再进行赋值:(*p2).age = 23。

结构体的内存布局

Go 语言中,结构体和它所包含的数据在内存中是以连续块的形式存在的,即使结构体中嵌套有其他的结构体,这在性能上带来了很大的优势。不像 Java 中的引用类型,一个对象和它里面包含的对象可能会在不同的内存空间中,这点和 Go 语言中的指针很像。

下面的例子清晰地说明了这些情况:type Rect1 struct {Min, Max Point }

type Rect2 struct {Min, Max *Point }

更多go语言知识请关注PHP中文网go语言教程栏目。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Go语言中,结构体初始化可以通过多种方式来实现。一种常见的方式是使用键值对进行初始化。例如,我们可以先定义一个结构体类型,然后使用键值对的方式来分配内存并初始化结构体的成员变量。这样做的好处是可以明确指定每个成员变量的值。另外,键值对初始化是可选的,即可以只初始化部分成员变量,而不用初始化所有成员变量。当不初始化成员变量时,匿名结构体的格式变为:ns := struct { 字段1 字段类型1 字段2 字段类型2 … }。 还有一种方式是使用多个值的列表来初始化结构体。这种方式不需要使用键值对,而是直接通过给出每个成员变量的值来完成初始化。需要注意的是,这种方式需要按照结构体定义的顺序依次给出每个成员变量的值[1]。 总之,对于Go语言结构体初始化,可以使用键值对初始化或者使用多个值的列表初始化。具体选择哪种方式取决于个人的需求和习惯。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [Go语言结构体如何进行初始化](https://blog.csdn.net/weixin_52723461/article/details/124819621)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值