[Day 6] -『 GO语言学习笔记』- 值 vs. 指标(pointers)

以下笔记摘录自『 The Go Workshop 』。

值的储存

Go语言采用了一个简单的记忆体管理系统叫堆叠(stack),每个参数都会在堆叠中获得自己的记忆体,缺点是有越多值在函式之间传递,这样重复的动作就会消耗越多的记忆体。

但其实还有一种在函式传值得替代方式,使用的记忆体较少,这种方式不会复制值,而是建立称指标(pointer)的东西传递给函式。

指标的储存

建立一个指标後,Go语言会将值放在所谓的堆积(heap)记忆体空间,堆积允许一个值存在,直到没有任何指标参照到他为止。Go语言会用所谓的垃圾回收机制(garbage collection)程序来回收这些记忆体。这种机制会在背景定期运作,无需特别操心。

Remark:
有时就算值没有设置任何指标,也会因为其他原因被放进堆积里面,值究竟该放到堆叠还是堆积上,我们无法介入,因为记忆体管理并非Go规格的一部分,而是被视为内部实作细节,所以上述所说的特性只是一般性指引,非铁则。

指标会有未设定(is not set)的状态,他没有储存目标值的地址时会回传nil,而nil这个特殊值在Go语言中代表无值。

取得指标

  1. 把 * 算符放在型别前,以此方法宣告的指标变数初始值为nil。
var <变数> *<型别>
  1. 内建函式new()可以达到赋值。
<变数> := new(<型别>)
var <变数> = new(<型别>)
  1. 取得某个既有变数的指标使用 & 算符
<变数 1> := &<变数 2>

从指标取得值

若要真正取得指标的关联值(及指标指向的记忆体所储存的内容),必须把 * 算符放在变数前面解除(derederence)指标参照,真正取值。

<值> = *<指标变数>

常见错误是尝试去解除一个无值指标(亦即nil),Go编辑器无法事先警告这点,所以最好养成习惯在解除指标的参照前,先检查它是否是nil。

For example,

package main

import (
	"fmt"
)

func main() {
	var count1 *int
	count2 := new(int)
	countTemp := 5
	count3 := &countTemp

	if count1 != nil {
		fmt.Printf("count1: %#v\n", *count1)
	}
	if count2 != nil {
		fmt.Printf("count2: %#v\n", *count2)
	}
	if count3 != nil {
		fmt.Printf("count3: %#v\n", *count3)
	}
}

//输出
count2: 0
count3: 5

<<:  冒险村05 - Release Drafter

>>:  VM 执行个体 (二)

FUNCTION

相信大家在学其他语言的时候,也常常会用的function的概念。但还是不免俗地来跟它聊聊。毕竟还是有...

Day 2-什麽是单元测试及何谓优秀的单元测试? (基础-1)

最初的单元测试传统定义 在 Roy Osherove 撰写的单元测试的艺术中,1970 年代就已经有...

Day17 Laravel - artisan

昨天用到了migrate,前天用到了serve,在Laravel框架下可以利用artisan指令介面...

day18_Windows ARM 的音乐之旅

音乐播放器 虽然 Mac Os , Linux, Windows 都内建了音乐播放器,但他们仍有一些...

[C]如何写一个 makefile

func1.h #ifndef _FUNC1_H_ #define _FUNC1_H_ void f...