面向对象编程强调数据和操作绑定,办法是有状态的,自身可能会批改数据。因而编程时确定办法是否会批改原始数据尤其要害。少数从其余语言转到 Go 语言的开发者,都会首先理解 Go 语言传递参数的时候到底是 “传值” 还是 “传援用”。如果第一门开发语言是 C 语言或者 C++ 的开发者,还会辨别下什么时候 “传指针”。

概念

什么是内存?

能够把内存想想为一系列单元格,一个个排列成一行,每个单元格都有一个惟一的编号。编号程序递增,代表内存的地位,也即是内存地址。

每个单元格都能够寄存一个值,能够通过编号读取和替换单元格内的先前写入的值。

什么是变量?

蹩脚的是,如果间接应用编号编程,就须要开发者本人治理内存,也难以和其余程序同时运行,极大的减少了编写大型程序的难度。

为了解决这个问题,就须要引入“变量”的概念。变量只是编号的假名、标签或昵称。

var a = 6var b = a * 3

什么是指针?

而指针的值是另一个变量的编号。指针指向变量的内存地址,就像变量代表值的内存地址一样。

func main() {        a := 200        b := &a        *b++        fmt.Println(a)}

什么是援用?

在 C++ 语言中,为现有变量申明别名,称为援用变量。如代码所示,a、b、c 三个变量均共享同一内存地址

#include <stdio.h>int main() {        int a = 10;        int &b = a;        int &c = b;        printf("%p %p %p\n", &a, &b, &c); // 0x7ffe114f0b14 0x7ffe114f0b14 0x7ffe114f0b14        return 0;}

Go 语言没有援用类型

Go 程序能够创立指向对立内存地址的变量,但无奈创立共享雷同内存地址的两个变量。如代码所示,b 和 c 具备雷同的值(a的地址)然而,b 和 c 的内存地址是惟一的。更新 b 的内容对 c 没有影响。

package mainimport "fmt"func main() {        var a int        var b, c = &a, &a        fmt.Println(b, c)   // 0x1040a124 0x1040a124        fmt.Println(&b, &c) // 0x1040c108 0x1040c110}

2013年4月3日,“援用类型”的概念已从 Go 标准中齐全删除,当初 Go 标准中的“援用”,没有一个代表“援用类型”的概念。

指针是类型吗?

指针是类型吗?这个问题可能在 C 或 C++ 中会有比拟大的一致,然而在 Go 语言中十分明确,毫无疑问:是的。

A pointer type denotes the set of all pointers to variables of a given type, called the base type of the pointer. The value of an uninitialized pointer is nil.

既然有类型,就有类型的实例:值,类型和值是截然不同的两个概念。显然,在 Go 语言中,当谈到指针时,蕴含 “指针类型” 和 “指针值”。

同时,为了防止指针引入的危险, Go 语言对指针做了不少的束缚,如下:

  1. 指针值不反对数学运算
var p *intp++

你不能更改指针指向的地位,除非赋值另外一个地址给它。同时也就不反对 Array-Pointer Duality。

  1. base type 不同的指针值,无奈间接相互赋值
type MyInt int64type Ta    *int64type Tb    *MyInt// 4 nil pointers of different types.var pa0 Tavar pa1 *int64var pb0 Tbvar pb1 *MyInt   // None of the following 3 lines compile ok./*_ = pa0 == pb0_ = pa1 == pb1_ = pa0 == Tb(nil)*/
  1. 返回局部变量的指针是平安的
func f() *int {   i := 1  return &i}

指针总结

应用过 C/C++ 语言的开发者,习惯应用的不平安的指针是 unsafe.Pointer,而非一般的指针。

int* valFirstintptr_t valSecondvoid* valThird

vs

int* valFirsttype intptr_t *intintptr_t valSecondunsafe.Pointer valThird

比照服用,成果更佳。

本文作者:cyningsun
本文地址: https://www.cyningsun.com/08-...
版权申明:本博客所有文章除特地申明外,均采纳 CC BY-NC-ND 3.0 CN 许可协定。转载请注明出处!