[Go语言]从Docker源码学习Go——指针和Structs
这两天在看reflect这个包在Docker中的使用时,遇到了各种问题,最后虽然知道怎么用了。
但是对于这块的原理还不是太懂,于是把"THE WAY TO GO"中关键的几章看了下。
继续坚持往下写,争取能说明白。
源码
还是先看Docker中源码, docker/api/client/cli.go
type DockerCli struct {
proto string
addr string
configFile *registry.ConfigFile
in io.ReadCloser
out io.Writer
err io.Writer
isTerminal bool
terminalFd uintptr
tlsConfig *tls.Config
scheme string
} ... func NewDockerCli(in io.ReadCloser, out, err io.Writer, proto, addr string, tlsConfig *tls.Config) *DockerCli {
...
return &DockerCli{
proto: proto,
addr: addr,
in: in,
out: out,
err: err,
isTerminal: isTerminal,
terminalFd: terminalFd,
tlsConfig: tlsConfig,
scheme: scheme,
}
}
先定义了一个struct,然后定义一个初始化的方法(方法内部初始化了一个struct,并返回其地址。)
指针
首先介绍一下go中的指针
我们在程序中定义一个变量,它在内存中被分配了一块空间,这块空间内存储的值就是变量的值,而这块空间的地址就可以赋值给一个指针。
指针内存放的是一个变量的内存地址,而不是真实的变量值。
声明一个指针用下面的方式( type 前面带 * 符号)
var intP *int
给指针赋值用 & 符号
i1 :=
intP = &i1
通过在指针变量前面添加 * 符号,你可以获得指针指向变量的值。
int1 == *(&int1)
在传值过程中尽量使用指针,这可以大大的减少内存开支,并提高传值速度。
不过有一个缺点是,在获得值时,由于多加了一层关系,所以会在这部分的性能上稍微慢一点。
struct使用
struct格式
type identifier struct {
field1 type1
field2 type2
...
}
struct初始化, 看下面例子中的3种情况就明白了。
// main
package main import "strings" type Person struct {
firstName string
lastName string
} func upPerson(p *Person) {
p.firstName = strings.ToUpper(p.firstName)
p.lastName = strings.ToUpper(p.lastName)
} func main() {
//1 - struct as a value type:
var pers1 Person
pers1.firstName = "Lemon"
pers1.lastName = "Bar"
upPerson(&pers1) //2 - struct as a pointer:
pers2 := new(Person)
pers2.firstName = "Lemon"
pers2.lastName = "Bar"
//(*pers2).lastName = "Bar" //this is also valid
upPerson(pers2) //3 - struct as a literal:
pers3 := &Person{"Lemon", "Bar"}
//pers3 := &Person{firstName:"Lemon",lastName:"Bar"} //this is also valid
upPerson(pers3)
}
注:new出来的是指针
我们除了可以直接初始化外,也可以通过定义工厂方法的形式来进行初始化
func NewDockerCli(in io.ReadCloser, out, err io.Writer, proto, addr string, tlsConfig *tls.Config) *DockerCli {
...
}
注:如果想让这个struct在所属的package外,只能通过工厂方法来初始化,可以把struct名字的首字母改成小写,也就是private的,package外就只能通过工厂方法进行初始化了。
匿名fields
匿名的fields可以实现其它语言中继承的功能
package main type innerS struct {
in1 int
in2 int
} type outerS struct {
b int
c float32
int //anonymous field
innerS //anonymous field
} func main() {
outer := new(outerS)
outer.in1 = //outerS.in1 is innerS.in1
outer.in2 = //outerS.in2 is innerS.in2
outer.int = //int is also the anonymous filed name outer2 := outerS{, 6.7, , innerS{, }} //outerS can also be initialized in this format
}
匿名struct里面的filed就变成外面struct的field。
注:在一个struct内,对于每种类型,只能有一个匿名类型的field。
名字冲突问题
由于一个struct里面可以包含多个匿名的不同类型的struct,那当有名字相同的filed时,go怎么处理呢?
1. outer field比inner field优先级更高,也就是外面的会覆盖掉里面的。
2. 如果两个field层级一样
a. 如果这个field名字,没有被用到的话,不会有问题。
b. 如果被用到了,会有编译错误。
[Go语言]从Docker源码学习Go——指针和Structs的更多相关文章
- [Go语言]从Docker源码学习Go——结构和函数的定义
Docker在最近很火,而作为Docker的开发语言-Go也再次被大家提到. 已经使用Docker一段时间了,但是对于源码,尤其是其开发语言Go却一直是一知半解. 最近准备利用空余时间从Docker源 ...
- [Go语言]从Docker源码学习Go——function和method
function和method关系 method是针对某一类型定义的function, function可以单独调用,method必须针对某一类型的实例进行调用 //function 调用方式 pac ...
- [Go语言]从Docker源码学习Go——if语句和map结构
if语句 继续看docker.go文件的main函数 if reexec.Init() { return } go语言的if不需要像其它语言那样必须加括号,而且,可以在判断以前,增加赋值语句 语法 I ...
- [Go语言]从Docker源码学习Go——init()方法和identifier首字母大小写区分
init()方法 如果想在一个go文件里,进行一些初始化的工作,可以把代码放到init()方法中. init()方法先被执行. func init() { // initialization of p ...
- [Go语言]从Docker源码学习Go——main函数
Go程序从main包下的main函数开始执行,当main执行结束后,程序退出. Docker的main函数在 docker/docker/docker.go package main //Import ...
- [Go语言]从Docker源码学习Go——Interfaces
Interface定义: type Namer interface { Method1(param_list) return_type Method2(param_list) return_type ...
- Go语言 context包源码学习
你必须非常努力,才能看起来毫不费力! 微信搜索公众号[ 漫漫Coding路 ],一起From Zero To Hero ! 前言 日常 Go 开发中,Context 包是用的最多的一个了,几乎所有函数 ...
- Docker源码分析(三):Docker Daemon启动
1 前言 Docker诞生以来,便引领了轻量级虚拟化容器领域的技术热潮.在这一潮流下,Google.IBM.Redhat等业界翘楚纷纷加入Docker阵营.虽然目前Docker仍然主要基于Linux平 ...
- Docker源码分析(二):Docker Client创建与命令执行
1. 前言 如今,Docker作为业界领先的轻量级虚拟化容器管理引擎,给全球开发者提供了一种新颖.便捷的软件集成测试与部署之道.在团队开发软件时,Docker可以提供可复用的运行环境.灵活的资源配置. ...
随机推荐
- 网络请求框架---Volley
去年的Google I/O大会为android开发者带来了一个网络请求框架,它的名字叫做Volley.Volley诞生的使命就是让Android的网络请求更快,更健壮,而且它的网络通信的实现是基于Ht ...
- Linux命令-网络命令:netstat
netstat -tlun 查看本机监听tcp.udp显示IP地址和端口号 netstat -an 可以查看本机正在连接的所有信息 netstat -rn 可以查看本机网关 windows里面的net ...
- python-数据结构Data Structure1
四种数据结构: 列表list = [val1,val2,val3,val4]字典dict = {key1:val1,key2:val2}元组tuple = (val2,val2,val3,val4)集 ...
- Hyper-V 虚拟机无法上网的解决方法
创建一个虚拟机网络交换机 2 创建一个 外部网络如下图所示: 3 添加一个旧版的网络适配器: 4 设置旧版网络适配器: END XP系统的情况 1 启动虚拟机,设置虚拟机IP: 2 输入http:// ...
- 【转载】Oracle数据字典详解
转自:http://czmmiao.iteye.com/blog/1258462 Oracle数据字典概述 数据库是数据的集合,数据库维护和管理这用户的数据,那么这些用户数据表都存在哪里,用户的信息是 ...
- Atitit.ati orm的设计and架构总结 适用于java c# php版
Atitit.ati orm的设计and架构总结 适用于java c# php版 1. Orm的目标1 1.1. 动态obj1 1.2. Hb的api(meger,save,update,del)1 ...
- Web前端的状态管理(State Management)
背景 我相信很多朋友跟我一样,初次听到什么Flux, Redux, Vuex,状态管理的时候是一脸懵逼的.因为在外面之前前端大部分开发的时候,根本没有那么多的概念.自从ReactJS火爆后,什么Flu ...
- 分页技术框架(Pager-taglib)学习三(pager-taglib中传递参数时中文乱码问题)
一.问题描述 问题: 使用<pg:param name="key" />标签传递中文参数时,会有乱码. 原因: 因为它默认是用gb2312来对添加的参数进行编码,如果你 ...
- python-hanoi
#!/usr/bin/env python #-*- coding:utf-8 -*- ############################ #File Name: hanoi.py #Autho ...
- python学习之os.walk()
os.walk(top,topdown = True,onerror = None,followlinks = False) 参数 top -- 根目录下的每一个文件夹(包含它自己), 产生3-元组 ...