4.4.2 值类型和引用类型

所有像 int、float、bool 和 string 这些基本类型都属于值类型,使用这些类型的变量直接指向存在内存中的值。

Go 语言的取地址符是 &,放到一个变量前使用就会返回相应变量的内存地址。

示例 4.22 string_pointer.go

package main
import "fmt"
func main() {
s := "good bye"
var p *string = &s
*p = "ciao"
fmt.Printf("Here is the pointer p: %p\n", p) // prints address
fmt.Printf("Here is the string *p: %s\n", *p) // prints string
fmt.Printf("Here is the string s: %s\n", s) // prints same string
}

输出:

Here is the pointer p: 0x2540820
Here is the string *p: ciao
Here is the string s: ciao

通过对 *p 赋另一个值来更改“对象”,这样 s 也会随之更改。

内存示意图如下:

传递指针给函数不但可以节省内存(因为没有复制变量的值),而且赋予了函数直接修改外部变量的能力,所以被修改的变量不再需要使用 return 返回。如下的例子,reply 是一个指向 int 变量的指针,通过这个指针,我们在函数内修改了这个 int 变量的数值。

示例 6.6 side_effect.go

package main

import (
"fmt"
) // this function changes reply:
func Multiply(a, b int, reply *int) {
*reply = a * b
} func main() {
n := 0
reply := &n
Multiply(10, 5, reply)
fmt.Println("Multiply:", *reply) // Multiply: 50
}

在 Go 语言中,指针(第 4.9 节)属于引用类型,其它的引用类型还包括 slices(第 7 章),maps(第 8 章)和 channel(第 13 章)。被引用的变量会存储在堆中,以便进行垃圾回收,且比栈拥有更大的内存空间。

在函数调用时,像切片(slice)、字典(map)、接口(interface)、通道(channel)这样的引用类型都是默认使用引用传递(即使没有显式的指出指针)。

4.4.5 init 函数

变量除了可以在全局声明中初始化,也可以在 init 函数中初始化。这是一类非常特殊的函数,它不能够被人为调用,而是在每个包完成初始化后自动执行,并且执行优先级比 main 函数高。

每一个源文件都可以包含一个或多个 init 函数。初始化总是以单线程执行,并且按照包的依赖关系顺序执行。

一个可能的用途是在开始执行程序之前对数据进行检验或修复,以保证程序状态的正确性。

示例 4.6 init.go:

package trans

import "math"

var Pi float64

func init() {
Pi = 4 * math.Atan(1) // init() function computes Pi
}

在它的 init 函数中计算变量 Pi 的初始值。

示例 4.7 user_init.go 中导入了包 trans(在相同的路径中)并且使用到了变量 Pi:

package main

import (
"fmt"
"./trans"
) var twoPi = 2 * trans.Pi func main() {
fmt.Printf("2*Pi = %g\n", twoPi) // 2*Pi = 6.283185307179586
}

init 函数也经常被用在当一个程序开始之前调用后台执行的 goroutine,如下面这个例子当中的 backend()

func init() {
// setup preparations
go backend()
}

最新文章

  1. Linux 中优秀的文本化编辑思想大碰撞(Markdown、LaTeX、MathJax)
  2. 【前端性能】必须要掌握的原生JS实现JQuery
  3. ArcGIS API ArcGISDynamicMapServiceLayer.setVisibleLayers对带有GroupLayer图层组的数据无效(针对LayerInfo)问题探讨
  4. 【转】NI语法 JNI参考 JNI函数大全
  5. (2015年郑州轻工业学院ACM校赛题) C 数列
  6. 从WinMain开始
  7. Windows Phone开发(45):推送通知大结局——Raw通知
  8. C# 手机格式验证
  9. 简单java web应用程序搭建与部署
  10. osap一站式分析模型
  11. Mysql生产指定时间段随机日期函数
  12. Django的安装和启动
  13. Eclipse+Maven整合开发Java项目(一)➣Maven基础环境配置
  14. SQL语句汇总(三)——聚合函数、分组、子查询及组合查询
  15. Asp.NET websocket,Asp.NET MVC 使用 SignalR 实现推送功能一(Hubs 在线聊天室)
  16. flask中的宏
  17. 最新OFFICE 0day漏洞分析
  18. [转]JVM运行时内存结构
  19. Spring定时(任务)刷新-quartz
  20. Eclipse中使用Maven创建项目 (转)

热门文章

  1. python实现二叉树的遍历以及基本操作
  2. zabbix web监控
  3. STL++?pb_ds平板电视初步探索
  4. notepad++使用NppFTP连接linux,编写shell脚本无法保存上传的问题
  5. 洛谷 3979 BZOJ 3083 遥远的国度
  6. go 语言学习指南(一)
  7. BZOJ 1834 Luogu P2604 [ZJOI2010]网络扩容 (最小费用最大流)
  8. java 项目连接MySQL数据库
  9. Java8-如何将List转变为逗号分隔的字符串--https://blog.csdn.net/benjaminlee1/article/details/72860845
  10. sdibt 1251 进化树问题