go声明和初始化

当我们第一次看见变量和声明时,我们仅仅看见一些内置的类型,比如整型和字符串。现在我们将学习结构体,并且我们会深入学习包括指针的内容。

通过一种最简单的方式去创建一个结构体值类型:

goku := Saiyan{

Name: "Goku",

Power: 9000,

}

注意:上面的结构体中,结尾的逗号,是不能省的。如果没有逗号,编译器会给出一个错误。你将喜欢上这种一致性要求,特别是如果你已经使用一种相反的语言或格式。

我们不需要给结构体设置任何值甚至任何字段。这2中方式都是有效的:

goku := Saiyan{}

// 或者

goku := Saiyan{Name: "Goku"}

goku.Power = 9000

这就像一个未赋值的变量一样,结构体的字段也会有一个0值。

另外,你也可以省略字段的名字,按字段的顺序进行声明(尽管为了简洁起见,你尽量在结构体只有少量字段时才使用这种方式):

goku := Saiyan{"Goku", 9000}

上面的例子主要是声明了一个变量goku,并给它赋值。

尽管在大多数时候,我们不希望一个变量直接关联一个值,而是希望一个指针指向变量的值。指针是一个内存地址。通过指针可以找到这个变量实际的值。这是一种间接的取值。严格地说,这与存在一个房子并指向另外一个房子有一些区别。

为什么我们需要一个指针指向一个值,而不需要一个实际值。这主要是因为在go语言中,函数的参数传递都是按值传递,即传递的是一个拷贝。了解到这点,下面程序会打印什么?

func main() {

goku := Saiyan{"Goku", 9000}

Super(goku)

fmt.Println(goku.Power)

}

func Super(s Saiyan) {

s.Power += 10000

}

答案是9000,不是19000。为什么?因为Super只是改变了goku的一个拷贝,所以在Super中的改变不会调用者中反应出来。如果你希望答案是19000,我们需要传递一个指向我们值的指针:

func main() {

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

Super(goku)

fmt.Println(goku.Power)

}

func Super(s *Saiyan) {

s.Power += 10000

}

我们改变了2个地方。首先是使用了&操作符去获得我们值的地址(&叫取地址符)。接下来,我们改变了Super接受的参数类型。之前我们是传递一个Saiyan的值类型,现在我们传递了一个地址类型*Saiyan,这里的*X表示一个指向类型X的一个指针。显而易见,Saiyan和*Saiyan类型之间有一定的联系,但是它们是两种不同的类型。

需要指出的是,我们现在传递给Super参数的仍然是goku的值拷贝。只是现在goku的值变成了一个地址。这个地址拷贝和源地址相同。可以认为它类似一个指向餐厅方向的拷贝,这就间接服务于我们。虽然是一个拷贝,但是和源地址一样,也指向同一个餐厅。

我们能证明这是一个拷贝,通过试着去改变它指向的地方(这可能不是你想做的):

func main() {

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

Super(goku)

fmt.Println(goku.Power)

}

func Super(s *Saiyan) {

s = &Saiyan{"Gohan", 1000}

}

上面的代码在此输出了9000。很多语言也有类似的行为,包括ruby、python、java和c#。go某种程度上和c#一样,只是让事实可见。

显而易见,复制一个指针变量的开销比复制一个复杂的结构体小。在一个64的系统上,指针的大小只有64位。如果我们的结构体有很多字段,创建一个结构体的拷贝会有很大的性能开销。指针的真正意义就是通过指针可以共享值。我们想通过Super去改变goku的拷贝或者改变共享的goku值本身?

这里不是说你需要一直使用指针。本章的结尾,在我们学到更多关于结构体使用的内容之后。我们将重新审视值类型和指针类型的问题。

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

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

    Go 不是像 C ++,Java,Ruby和C#一样的面向对象的(OO)语言.它没有对象和继承的概念,也没有很多与面向对象相关的概念,例如多态和重载. Go所具有的是结构体的概念,可以将一些方法和结构 ...

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

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

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

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

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

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

  5. golang 初始化并赋值_Go语言创建、初始化数组的常见方式汇总

    本文实例总结了Go语言创建.初始化数组的常见方式.分享给大家供大家参考.具体分析如下: Go语言的语法很灵活,以下展示了创建并初始化数组的多种方式: //数组初始化的各种方式 func arraySl ...

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

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

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

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

  8. JAVA---int数组声明与初始化

    JAVA---int数组声明与初始化 JAVA中int数组声明与初始化: 有3种正确方式同时进行声明与初始化:分别为new int[num],{}以及new int[]{...}.注意,当使用new ...

  9. Go开发 之 基础语法(变量的声明、初始化、作用域,匿名变量,多变量赋值,变量逃逸分析)

    文章目录 1.变量的声明 1.1.标准格式 1.2.简短格式 1.3.批量格式 2.变量的初始化 2.1.标准格式 2.2.编译器推导类型的格式 2.3.声明并初始化 3.多个变量同时赋值 4.匿名变 ...

最新文章

  1. 【收藏】SpringBlade开发手册地址
  2. 数据产品-指标体系与数据采集
  3. web应用程序和Web网站区别
  4. python一对一视频教学-问Python,一对一直播开发需要推流器吗?
  5. html下拉菜单的某个值被选定,使用JavaScript在下拉列表中获取选定的值?
  6. 基于Python+Django的电影推荐系统毕业设计源码
  7. 如何借助表格优化直通车分时折扣
  8. 滑铁卢大学容易转计算机专业吗,滑铁卢大学计算机科学专业好吗
  9. 1927年12月31日午夜一秒谜案
  10. 3DM:phase wrapping
  11. 一体化红外接收头有两种
  12. hadoop:常用web界面和命令
  13. IOS 内购IAP 自动订阅收据验证返回结构体
  14. 用python实现12306抢票
  15. r720 linux 双系统,联想R720拯救者i5 7300黑苹果MacOS10.14.2安装和双系统引导
  16. 轴承故障诊断之快速谱峭度法 Matlab 代码说明
  17. binutils工具集
  18. LNMP环境搭建网站
  19. div 设置相对比例 即div width 100 无效
  20. 新建maven项目时,Run中报警告:No archetype found in remote catalog. Defaulting to internal catalo在远程目录中没有找到原型。

热门文章

  1. 上交浙大哈工西交-保研经验全分享
  2. CSS3引用SVG base64的方法
  3. Rotated_Faster_Rcnn
  4. 香港两日游的那些事儿
  5. 五级工程师,你处在第几级
  6. 数据结构——线性表的顺序存储结构
  7. 架构师·软件架构设计·ADD
  8. 关于C语言的数组赋值和数组下标越界问题
  9. Linux中dlfcn库相关学习
  10. 哪款运动蓝牙耳机好用、运动真无线蓝牙耳机推荐