博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Go语言中的Struct
阅读量:6333 次
发布时间:2019-06-22

本文共 3721 字,大约阅读时间需要 12 分钟。

一、Go语言中没有像C#、Java一样的Class,只有Struct这样的结构体。Go语言使用type关键字来定义一个类型。

如下:

type User struct {   Name string   Age int32   Sex int16   AvatarUrl string}

 

二、Struct的声明以及初始化

初始化方法一:直接定义,通过变量名.成员名的方式赋值

//初始化方法1var user1 Useruser1.Name = "BigOrange"user1.Age = 20user1.Sex = 1user1.AvatarUrl = "xxxxxxx"fmt.Println("User1:",user1)

初始化方法二:直接通过{}进行初始化,这点和C#不一样,C#初始化的时候一般用new,例如 var user  = new User{xxxxx,xxxxx,xxxx}

//初始化方法2var user2 User = User{   Name:"BigBanana",   Age:23,   Sex:0,   AvatarUrl:"yyyyyyyyyyy",}fmt.Println("User2:",user2)//初始化方法2简化 user3 := User{   Name:"BigBanana",   Age:23,   Sex:0,   AvatarUrl:"yyyyyyyyyyy",}fmt.Println("User3:",user3)

  

三、Struct的指针

Struct的指针比较简单,就是通过&获取地址,此外还可以用new来返回一个对象的指针

 

var user4 *User = &User{    Name:"BigPeach",    Age:22,    Sex:1,    AvatarUrl:"zzzzzzz", }fmt.Println("User4:",user4)fmt.Println("User4:",*user4)

 

user5 := new(User)user5.Name="BigGrape"user5.Age= 25user5.Sex= 1user5.AvatarUrl= "mmmmmmmmm"fmt.Println("User5:",user5)fmt.Println("User5:",*user5)

上面第二种方式可能会有些疑问,user5不是一个指针类型吗?怎么和上面的值类型一样直接用【变量名.成员】 的方式进行赋值了呢? 不是应该 (*user5).Name 这样吗?没有错!

这是GO语言实现的一个语法糖,实际上GO语言会帮我转换。

 

四、Struct成员的内存布局以及实现构造函数

例如下面这样的一段代码

 

package mainimport "fmt"type AddressDemo struct {   addr1 int32   addr2 int32   addr3 int32}func main(){   addr := new(AddressDemo)   fmt.Println("add1地址:",&addr.addr1)   fmt.Println("add2地址:",&addr.addr2)   fmt.Println("add3地址:",&addr.addr3)}

结果:

add1地址: 0xc042060080add2地址: 0xc042060084add3地址: 0xc042060088

可以看出来,addr1、addr2、addr3都是int32,都是占用了4个字节,他们的地址分配都是连续的

For example: 下面这个User包,就实现了一个NewUser的方法,他就是构造函数

package Usertype User struct {   Name string   Age int32   Sex int16   AvatarUrl string}func NewUser(name string , age int32,sex int16,avatarUrl string) *User{   user:=new(User)   user.Name = name   user.Age = age   user.Sex = sex   user.AvatarUrl = avatarUrl   return user}

 

五、Struct中的匿名字段和嵌套

可以像下面这样声明:后两个字段没有名字

type Class struct {   Name string   int   string}

使用的时候,对于匿名的字段,直接赋值就可以了

class1:=Class{   Name:"Class1",   int:123,   string:"sssssss",}fmt.Println("class1:",class1)

结构体的嵌套

type User struct {   Name string   Age int32   Sex int16   AvatarUrl string}type Class struct {   Name string}type Student struct {   User User   Class Class}

使用:

func main() {   stu:=new(User.Student)      stu.Class = User.Class{      Name:"5-2",   }      stu.User = User.User {       Name:"BigBanana",      Sex:1,      Age:12,      AvatarUrl:"asdasdasd",   }      fmt.Println(stu)}

如果是匿名结构体嵌套呢?修改一下Student

type Student struct {   User User   Class}

使用在对Class这个成员进行赋值的时候,可以发现,既可以使用

stu.Class = User.Class{      Name:"5-2",   }

也可以使用Name直接赋值,顺序就是现在当前的结构体找,找不到再从匿名结构体中查找,正好找到Class里面有Name

stu.Name = "5-2"

如果Class和User都是匿名结构嵌套,但是他们里面都有Name,当我们使用stu.Name的时候,那他访问的是Class里的Name还是User里面的Name? 那么岂不是冲突了? 如何处理冲突?

当我试图给stu.Name赋值的时候,编译器报错了,内容如下,也就是它找不到应该给谁赋值。

这时候要解决这个冲突,必须指定是哪个匿名字段里面的Name

stu:=new(User.Student)stu.User.Name = "123123"stu.Class.Name = "5-2"stu.User = User.User {   Name:"BigBanana",   Sex:1,   Age:12,   AvatarUrl:"asdasdasd",}

 

六、结构体内字段的可见性

和包一样,小写的字段外部不可见,大写的外部可见

 

七、结构体的Tag

tag是结构体的元信息,可以在运行的时候通过反射的机制读出来。

怎么写tag?

以`作为开头和结尾,中间是key-value形式的字符串,每一个键值对以,作为分隔。例如

type User struct {   UserName string   `json:"userName",db:"User_Name"`   Age int32         `json:"age"`   Sex int16         `json:"sex"`   AvatarUrl string  `json:"avatarUrl",db:"Avatar_Url"`}

使用并运行:

func main() {   user := User.User {      UserName:"BigBanana",      Sex:1,      Age:12,      AvatarUrl:"asdasdasd",   }   fmt.Println(user)   data,_:=json.Marshal(user)   fmt.Println(string(data))   }

结果:

{
"userName":"BigBanana","age":12,"sex":1,"avatarUrl":"asdasdasd"}

可以看到,如果打了这个tag,会显示tag后面的标记名称。

此外:如果字段名称是小写,那么json输出的时候就不会有这个字段被打印了。

 

转载于:https://www.cnblogs.com/dcz2015/p/10770917.html

你可能感兴趣的文章
javaweb使用自定义id,快速编码与生成ID
查看>>
[leetcode] Add Two Numbers
查看>>
elasticsearch suggest 的几种使用-completion 的基本 使用
查看>>
04-【MongoDB入门教程】mongo命令行
查看>>
字符串与整数之间的转换
查看>>
断点传输HTTP和URL协议
查看>>
redis 数据类型详解 以及 redis适用场景场合
查看>>
mysql服务器的主从配置
查看>>
巧用AJAX技术,通过updatePanel控件实现局部刷新
查看>>
20140420技术交流活动总结
查看>>
SaltStack配置salt-api
查看>>
各种情况下block的类型
查看>>
ThinkPHP 3.2.x 集成极光推送指北
查看>>
js作用域链
查看>>
java中如何选择Collection Class--java线程(第3版)
查看>>
为运维人员插上腾飞更远的翅膀!
查看>>
Word 2003中编辑标记与格式标记大讨论
查看>>
从国内向海外转移域名经验谈
查看>>
浅谈apache与tomact的整合
查看>>
SQL Server vNext CTP1 on Linux
查看>>