1、定义一个结构体

type User struct {
userid int
username string
password string
}

2、初始化一个结构体

  有两种情况,一是得到结构体的对象,一是得到结构的对象指针,分别有三种方式:

 //第1种方式,先声明对象,再初始化
var player1 Player
player1.userid =
player1.username = "lina1"
player1.password = "" //第2种方式,声明同时初始化
player2 := Player{, "lina2", ""} //第3种方式,通过 field:value 形式初始化,该方式可以灵活初始化字段的顺序
player3 := Player{username: "lina3", password: "", userid: } //上面三种初始化方式都是生产对象的,相应如果想初始化得到对象指针的三种方法如下:
//第1种方式,使用 new 关键字
player4 := new(Player)
player4.userid =
player4.username = "lina4"
player4.password = "" //第2种方式,声明同时初始化
player5 := &Player{, "lina2", ""} //第3种方式,通过 field:value 形式初始化,该方式可以灵活初始化字段的顺序
player6 := &Player{username: "lina3", password: "", userid: }

3、对象与对象指针的区别(更确切的说应该是值类型和指针类型)

  与C/C++类似,GO语言也存在对象与对象的指针,但不同的是,GO语言中没有 -> 操作符来调用指针所属的成员,而与一般对象一样,都是使用 . 来调用。

  对于一个函数(或方法),如果函数的参数(或接收者)是对象指针时,表示此对象是可被修改的;相反的,如果是对象时,表示是不可修改的(但如果该对象本身就是引用类型,如 map\func\chan 等,则本质上是可以修改的)。所以一般的做法是,方法的接收者习惯性使用对象指针,而不是对象,一方面可以在想修改对象时进行修改,另一方面也减少参数传递的拷贝成本。

  另外,有一点尤为特殊,如果是作为函数的参数,则函数定义时,是使用对象还是对象指针,是有本质区别的,在使用对象作为参数的函数中,不能传入对象指针,同样的,在使用对象指针作为参数的函数中,也不能传入对象,否则编译器会报错。但如果是方法,则接收者定义为对象还是对象指针,都可以接收对象和对象指针的调用。下面我们来定义相关的函数和方法如下:

//传入 Player 对象参数
func print_obj(player Player) {
//player.username = "new"  //修改并不会影响传入的对象本身
log.Println("userid:", player.userid)
} //传入 Player 对象指针参数
func print_ptr(player *Player) {
player.username = "new"
log.Println("userid:", player.userid)
} //接收者为 Player 对象的方法,方法接收者的变量,按照 GO 语言的习惯一般不用 this/self ,而是使用接收者类型的第一个小写字母,可以看标准库中的代码风格。
func (p Player) m_print_obj() {
//p.username = "new"  //修改并不会影响传入的对象本身
  log.Println("self userid:", p.userid)
} //接收者为 Player 对象指针的方法
func (p *Player) m_print_ptr() {
  p.username = "new"
  log.Println("self userid:", p.userid)
}

  然后测试一下函数跟方法的调用:

    print_obj(player2)
//print_ptr(player2) //无法调用,编译出错
player2.m_print_obj()
player2.m_print_ptr() //print_obj(player6) //无法调用,编译出错
print_ptr(player6)
player6.m_print_obj()
player6.m_print_ptr()

  既然对于对象与对象指针的区别,方法的处理很特殊,那么将一个对象传入到接收者为对象指针的方法中,及将一个对象指针传入到一个接收者为对象的方法中,能不能修改传入对象的值呢?答案是,由方法的定义决定,而不是方法的调用者类型决定。

4、匿名字段

  结构体里的字段可以只有类型名,而没有字段名,这种字段称为匿名字段。匿名字段可以是一个结构体、切片等复合类型,也可以是 int 这样的简单类型。但建议不要把简单类型作为匿名字段。

type Pet struct {
id int
petname string
} type Player struct {
id int
Pet
int
} func main() {
var player1 Player
player1.petname = "pet1" //可以直接访问匿名字段中的成员,就像访问自己的成员一样
player1.int = //一般不推荐将简单类型作为匿名字段,如果有多个匿名的int,这里就没法处理了
player1.id = //如果外层跟内层字段名重复的话,优先取外层字段
player1.Pet.id = //如果外层跟内层字段名重复的话,可以通过这种形式来访问内层字段
}

一个命名为S的结构体类型将不能再包含S类型的成员:因为一个聚合的值不能包含它自身。(该限制同样适应于数组。)但是S类型的结构体可以包含*S指针类型的成员,这可以让我们创建递归的数据结构,比如链表和树结构等。

如果结构体没有任何成员的话就是空结构体,写作struct{}。它的大小为0,也不包含任何信息,但是有时候依然是有价值的。有些Go语言程序员用map带模拟set数据结构时,用它来代替map中布尔类型的value,只是强调key的重要性,但是因为节约的空间有限,而且语法比较复杂,所有我们通常避免避免这样的用法。

seen := make(map[string]struct{}) // set of strings
// ...
if _, ok := seen[s]; !ok {
seen[s] = struct{}{}
// ...first time seeing s...
}
结构体可以作为函数的参数和返回值,如果结构体较大,一般使用指针参数,而且如果要在函数修改结构体,则必须使用指针形式。go语言中所有的函数参数都是值拷贝。

如果结构体的全部成员都是可比较的,则该结构体也可比较,则可作为Map的key类型。

得意于匿名嵌入的特性,我们可以直接访问叶子属性而不需要给出完整的路径:


var w Wheel
w.X = 8 // equivalent to w.Circle.Point.X = 8
w.Y = 8 // equivalent to w.Circle.Point.Y = 8
w.Radius = 5 // equivalent to w.Circle.Radius = 5
w.Spokes = 20
 

不幸的是,结构体字面值并没有简短表示匿名成员的语法, 因此下面的语句都不能编译通过:


w = Wheel{8, 8, 5, 20}                       // compile error: unknown fields
w = Wheel{X: 8, Y: 8, Radius: 5, Spokes: 20} // compile error: unknown fields

到目前为止,我们看到匿名成员特性只是对访问嵌套成员的点运算符提供了简短的语法糖。稍后,我们将会看到匿名成员并不要求是结构体类型;其实任何命令的类型都可以作为结构体的匿名成员。但是为什么要嵌入一个没有任何子成员类型的匿名成员类型呢?

答案是匿名类型的方法集。简短的点运算符语法可以用于选择匿名成员嵌套的成员,也可以用于访问它们的方法。实际上,外层的结构体不仅仅是获得了匿名成员类型的所有成员,而且也获得了该类型导出的全部的方法。这个机制可以用于将一个有简单行为的对象组合成有复杂行为的对象。组合是Go语言中面向对象编程的核心

结体体定义时,可以为每一个字段添加一个 Tag,比如使用内置Json库时,就可能用到这个Tag。具体看元数据和反射。

golang笔记——struct的更多相关文章

  1. Golang笔记(二)面向对象的设计

    Golang笔记(二)面向对象的设计 Golang本质还是面向过程的语言,但它实现了一些OOP的特性,包括抽象.封装.继承和多态. 抽象和封装 Golang和C语言一样以struct为数据结构核心,不 ...

  2. GoLang获取struct的tag

    GoLang获取struct的tag内容:beego的ORM中也通过tag来定义参数的. 获取tag的内容是利用反射包来实现的.示例代码能清楚的看懂! package main import ( &q ...

  3. golang笔记1

    golang笔记1 go代码是用包来组织的,每个包有一个或多个go文件组成,这些go文件文件放在一个文件夹中 每个源文件开始都用一个package声明,指明本源文件属于哪个包 pakage声明后紧跟这 ...

  4. Golang笔记(一)简洁的语言风格

    Golang笔记(一)简洁的语言风格 概述 Golang继承了很多C语言的风格,寡人使用了十几年C语言,切换到Golang时上手很快,并且随着深入的使用,越来越喜欢这门语言.Golang最直观的感受是 ...

  5. golang 学习笔记 -- struct interface的使用

    一个 interface 类型定义了一个方法集做接口. 区分goalng的方法和函数 func go() { fmt.Println('go to home') } 这是函数 type car str ...

  6. golang print struct with key

    https://play.golang.org/p/YMfpuluzef 判断结构体是否为空 打印带attribute(key) 的结构体 package main import ( "fm ...

  7. Golang中Struct与DB中表字段通过反射自动映射 - sqlmapper

    Golang中操作数据库已经有现成的库"database/sql"可以用,但是"database/sql"只提供了最基础的操作接口: 对数据库中一张表的增删改查 ...

  8. Golang 笔记 1 基础、基本数据类型

    一.Go语言基础 1. 基础 Go语言中的标识符必须以字母(Unicode字母,PHP/JS可以用中文作为变量名)下划线开头.大写字母跟小写字母是不同的:Hello和hello是两个不同的名字.  G ...

  9. golang自定义struct字段标签

    原文链接: https://sosedoff.com/2016/07/16/golang-struct-tags.html struct是golang中最常使用的变量类型之一,几乎每个地方都有使用,从 ...

随机推荐

  1. Cookie无法读取

    问题描述:用谷歌调试可以看到,但是用js去读取的时候,一直提示undefined

  2. 第3章 Linux常用命令(5)_网络命令和挂载命令

    7. 网络命令 7.1 给用户发信息,以ctr+D保存结束 (1)write命令 命令名称 write 命令所在路径 /user/bin/write 执行权限 所有用户 语法 write <用户 ...

  3. ubuntu 14.04 以root权限启动chrome

    chrome版本 51.0.2704.103 How to run google chrome as root in linux - Unix & Linux Stack Exchange提示 ...

  4. three.js添加文字

    添加文字需要用到fontLoader,测试貌似只能异步.在success中回调. 对于中文字体,需要将ttf格式转换为json格式或者是js格式之后才能使用,不过一般转换之后的文件比较大.建议使用Fo ...

  5. Flink 1.1 – ResourceManager

    Flink resource manager的作用如图,   FlinkResourceManager /** * * <h1>Worker allocation steps</h1 ...

  6. 基于SuperSocket的IIS主动推送消息给android客户端

    在上一篇文章<基于mina框架的GPS设备与服务器之间的交互>中,提到之前一直使用superwebsocket框架做为IIS和APP通信的媒介,经常出现无法通信的问题,必须一天几次的手动回 ...

  7. RequireJS中的require如何返回模块

    requirejs中定义AMD模块规则如下: define(function(){ var ProductManager={ Create:function(){ console.log(" ...

  8. PlayMaker的应用

    PlayMaker属于一个可视化的状态机编辑工具,集成到了Unity的IDE里,在Unity的市场上很受欢迎,本人看见后第一感觉是跟CryEngine的那个状态机特别相似.CE的那个状态机编辑器其实是 ...

  9. spring的AOP

    最近公司项目中需要添加一个日志记录功能,就是可以清楚的看到谁在什么时间做了什么事情,因为项目已经运行很长时间,这个最初没有开来进来,所以就用spring的面向切面编程来实现这个功能.在做的时候对spr ...

  10. 2016 Web开发资源工具大搜罗

    来源于:https://zhuanlan.zhihu.com/p/22730771 作者:余博伦链接:https://zhuanlan.zhihu.com/p/22730771来源:知乎著作权归作者所 ...