Go 不是像 C ++,Java,Ruby和C#一样的面向对象的(OO)语言。它没有对象和继承的概念,也没有很多与面向对象相关的概念,例如多态和重载。

Go所具有的是结构体的概念,可以将一些方法和结构体关联。Go 还支持一种简单但有效的组合形式。 总的来说,它会使代码变的更简单,但在某一些场合,你会错过面向对象提供的一些特性。(值得指出的是,通过组合实现继承是一场古老的战斗呐喊,Go 是我用过的第一种坚定立场的语言,在这个问题上。)

虽然 Go 不会像你以前使用的面向对象语言一样,但是你会注意到结构的定义和类的定义之间有很多相似之处。下面的代码定义了一个简单的 Saiyan 结构体:

type Saiyan struct {

Name string

Power int

}

我们将看明白怎么往这个结构体添加一个方法,就像面向对象类,会有方法作为 它的一部分。在这之前,我们先要知道如何声明结构体。

声明和初始化

当我们第一次看到变量和声明时,我们只看了内置类型,比如整数和字符串。既然现在我们要讨论结构,那么我们需要把讨论范围扩展到指针。

创建结构的值的最简单的方式是:

goku := Saiyan{

Name: "Goku",

Power: 9000,

}

注意: 上述结构末尾的逗号 , 是必需的。没有它的话,编译器就会报错。你将会喜欢上这种必需的一致性,尤其当你使用一个与这种风格相反的语言或格式的时候。

我们不必设置所有或哪怕一个字段。下面这些都是有效的:

goku := Saiyan{}

// or

goku := Saiyan{Name: "Goku"}

goku.Power = 9000

就像未赋值的变量其值默认为 0 一样,字段也是如此。

此外,你可以不写字段名,依赖字段顺序去初始化结构体 (但是为了可读性,你应该把字段名写清楚):

goku := Saiyan{"Goku", 9000}

以上所有的示例都是声明变量 goku 并赋值。

许多时候,我们并不想让一个变量直接关联到值,而是让它的值为一个指针,通过指针关联到值。一个指针就是内存中的一个地址;指针的值就是实际值的地址。这是间接地获取值的方式。形象地来说,指针和实际值的关系就相当于房子和指向该房子的方向之间的关系。

为什么我们想要一个指针指向值而不是直接包含该值呢?这归结为 Go 中传递参数到函数的方式:镜像复制。知道了这个,尝试理解一下下面的代码呢?

func main() {

goku := Saiyan{"Power", 9000}

Super(goku)

fmt.Println(goku.Power)

}

func Super(s Saiyan) {

s.Power += 10000

}

上面程序运行的结果是 9000,而不是 19000,。为什么?因为 Super 修改了原始值 goku 的复制版本,而不是它本身,所以,Super 中的修改并不影响上层调用者。现在为了达到你的期望,我们可以传递一个指针到函数中:

func main() {

goku := &Saiyan{"Power", 9000}

Super(goku)

fmt.Println(goku.Power)

}

func Super(s *Saiyan) {

s.Power += 10000

}

这一次,我们修改了两处代码。第一个是使用了 & 操作符以获取值的地址(它就是 取地址 操作符)。然后,我们修改了 Super 参数期望的类型。它之前期望一个 Saiyan 类型,但是现在期望一个地址类型 *Saiyan,这里 *X 意思是 指向类型 X 值的指针 。很显然类型 Saiyan 和 *Saiyan 是有关系的,但是他们是不同的类型。

这里注意到我们仍然传递了一个 goku 的值的副本给 Super,但这时 goku 的值其实是一个地址。所以这个副本值也是一个与原值相等的地址,这就是我们间接传值的方式。想象一下,就像复制一个指向饭店的方向牌。你所拥有的是一个方向牌的副本,但是它仍然指向原来的饭店。

我们可以证实一下这是一个地址的副本,通过修改其指向的值(尽管这可能不是你真正想做的事情):

func main() {

goku := &Saiyan{"Power", 9000}

Super(goku)

fmt.Println(goku.Power)

}

func Super(s *Saiyan) {

s = &Saiyan{"Gohan", 1000}

}

上面的代码,又一次地输出 9000。就像许多语言表现的那样,包括 Ruby,Python, Java 和 C#,Go 以及部分的 C#,只是让这个事实变得更明显一些。

同样很明显的是,复制一个指针比复制一个复杂的结构的消耗小多了。在 64 位的机器上面,一个指针占据 64 bit 的空间。如果我们有一个包含很多字段的结构,创建它的副本将会是一个很昂贵的操作。指针的真正价值在于能够分享它所指向的值。我们是想让 Super 修改 goku 的副本还是修改共享的 goku 值本身呢?

所有这些并不是说你总应该使用指针。这章末尾,在我们见识了结构的更多功能以后,我们将重新检视 指针与值这个问题。

本译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接

我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。

golang 初始化并赋值_声明和初始化相关推荐

  1. golang 初始化并赋值_go声明和初始化

    go声明和初始化 当我们第一次看见变量和声明时,我们仅仅看见一些内置的类型,比如整型和字符串.现在我们将学习结构体,并且我们会深入学习包括指针的内容. 通过一种最简单的方式去创建一个结构体值类型: g ...

  2. 《C++ Primer 第五版》第二章(1-4小节)------基本内置类型,初始化和赋值及声明和定义,指针和引用,const和constexpr

    C++ Primer第二章的内容主要介绍了变量和基础类型,包括C++语言定义的基础内置类型.变量的定义及声明.符合类型如指针及引用的介绍和const及常量表达式constexpr的介绍,本次博客也从这 ...

  3. java 数组声明并初始化_Java数组的声明与初始化

    在<Java数组简介>一节中,我们已经了解了什么是数组.什么是基本数据类型的数组,那么大家是不是迫不及待地想知道一个基本数据类型的数组是什么样子的呢?下面我们就一起来揭开它神秘的面纱吧! ...

  4. byte初始化并赋值_一位数组的定义、赋值和初始化.note

    当数组中每个元素都只带有一个下标时,这种数组就是"一维数组".一维数组(one-dimensional array)实质上是一组相同类型数据的线性集合,是数组中最简单的一种数组. ...

  5. c++ stl队列初始化_声明,初始化和访问向量| C ++ STL

    c++ stl队列初始化 Here, we have to declare, initialize and access a vector in C++ STL. 在这里,我们必须声明,初始化和访问C ...

  6. java 声明变量 初始化_Java变量的声明和初始化

    Java 语言是强类型(strongly typed)语言,强类型包含以下两方面的含义:所有的变量必须先声明.后使用. 指定类型的变量只能接受类型与之匹配的值. 这意味着每个变量和每个表达式都有一个在 ...

  7. golang 初始化并赋值_嵌套Golang对象的初始化

    比如有这样一个对象: type ProductConfig struct { Site map[string]string } 对应的初始化可以如下写: 需要注意的几点: 其中的成员变量幅值不用&qu ...

  8. golang 初始化并赋值_golang 结构体初始化时赋值格式介绍

    golang在给结构体赋值初始值时,用:分割k,v值 x := ItemLog{ Id: GetUuid(), ItemId: u.Id, UsrId: "123", Name: ...

  9. php初始化函数赋值,PHP变量的初始化以及赋值方式介绍

    什么是变量 变量通俗的来说是一种容器.根据变量类型不同,容器的大小不一样,自然能存放的数据大小也不相同.在变量中存放的数据,我们称之为变量值. PHP 中的变量用一个美元符号后面跟变量名来表示.变量名 ...

最新文章

  1. 洛谷P4568 飞行路线 最短路k条免费
  2. 给FlvDownloader加了一个视频预览的功能
  3. opencv计算物体姿态旋转_OpenCV轮廓检测,计算物体旋转角度
  4. mongoose查询不到数据表中的数据的问题
  5. python转换为c代码_bash 转换为C代码
  6. 运用计算机计算包含排斥原理,离散数学包含及排斥原理.ppt
  7. Linux 查看ERROR日志方法
  8. 赞!卷积神经网络中十大拍案叫绝的操作
  9. python如何监听toast提示信息_python 怎样获取toast?
  10. 基于CUDA的三维VTI介质逆时偏移与ADCIGs提取
  11. java中各种集合的用法和比较
  12. layui修改窗口标题
  13. Java安装以及环境配置
  14. python中的数据分析库有哪些_全网最全数据分析师干货-python篇
  15. Hadoop生态圈-Azkaban实现文件上传到hdfs并执行MR数据清洗
  16. 第一冲刺阶段意见汇总
  17. 出行品类HarmonyOS高德地图集成过程分享
  18. 小米玩机------MIUI里那些你可能不知道的冷知识
  19. Utopia unlimited: reassessing American literary utopias【翻译】
  20. 计算机控制实验比例环节,实验报告1典型环节及其阶跃响应分析

热门文章

  1. 从零开始写Python爬虫 --- 1.2 BS4库的安装与使用
  2. 数据结构与算法——线性表的顺序储存结构
  3. Zabbix 监控(内容详细 供您参考)
  4. laravel源码分析
  5. php 六边形 属性图 能力数值图,css怎样做出六边形图片
  6. 不用插件给wordpress添加关键词和描述
  7. Python计算皮尔逊相关系数
  8. 七雄争霸服务器维护至几点,部分大区临时维护公告
  9. 后疫情时代,开元酒店集团挖需求、练内功、担责任
  10. 中国著名书画家王宪武