

Go 语言没有引用类型,指针也与众不同
source link: https://www.cyningsun.com/08-16-2021/go-has-no-reference-and-safe-pointer.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Go 语言没有引用类型,指针也与众不同
面向对象编程强调数据和操作绑定,方法是有状态的,本身可能会修改数据。因此编程时确定方法是否会修改原始数据尤其关键。多数从其他语言转到 Go 语言的开发者,都会首先了解 Go 语言传递参数的时候到底是 “传值” 还是 “传引用”。如果第一门开发语言是 C 语言或者 C++ 的开发者,还会区分下什么时候 “传指针”。
什么是内存?
可以把内存想想为一系列单元格,一个个排列成一行,每个单元格都有一个唯一的编号。编号顺序递增,代表内存的位置,也即是内存地址。
每个单元格都可以存放一个值,可以通过编号读取和替换单元格内的先前写入的值。
什么是变量?
糟糕的是,如果直接使用编号编程,就需要开发者自己管理内存,也难以和其他程序同时运行,极大的增加了编写大型程序的难度。
为了解决这个问题,就需要引入“变量”的概念。变量只是编号的假名、标签或昵称。
var a = 6
var 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 main
import "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 语言对指针做了不少的约束,如下:
- 指针值不支持数学运算
var p *int
p++
你不能更改指针指向的位置,除非赋值另外一个地址给它。同时也就不支持 Array-Pointer Duality。
- base type 不同的指针值,无法直接互相赋值
type MyInt int64
type Ta *int64
type Tb *MyInt
// 4 nil pointers of different types.
var pa0 Ta
var pa1 *int64
var pb0 Tb
var pb1 *MyInt
// None of the following 3 lines compile ok.
/*
_ = pa0 == pb0
_ = pa1 == pb1
_ = pa0 == Tb(nil)
*/
- 返回局部变量的指针是安全的
func f() *int {
i := 1
return &i
}
使用过 C/C++ 语言的开发者,习惯使用的不安全的指针是 unsafe.Pointer
,而非普通的指针。
int* valFirst
intptr_t valSecond
void* valThird
int* valFirst
type intptr_t *int
intptr_t valSecond
unsafe.Pointer valThird
对比服用,效果更佳。
本文作者:cyningsun
本文地址: https://www.cyningsun.com/08-16-2021/go-has-no-reference-and-safe-pointer.html
版权声明:本博客所有文章除特别声明外,均采用 CC BY-NC-ND 3.0 CN 许可协议。转载请注明出处!
Recommend
-
27
一,变量类型 变量分为值类型,指针类型和引用类型。 以如下变量定义和赋值语句为例: package main import( "fmt" ) func main(){ var a int = 1 p := &a fmt.Printf("%v\n", a)...
-
18
介绍 去年,英国国家网络安全中心(NCSC)报告了一个V8编译器中存在的安全漏洞,随后Google便悄悄修复了该漏洞。这个漏洞ID...
-
15
shared_ptr能和基于引用计数的智能指针混用吗? 2020-12-13...
-
11
简谈 C++ 中指针与引用的底层实现 发表于 2019-09-11...
-
11
Go语言类型断言、类型选择、指针、数组的问题以及生成二进制可执行文件去部署项目 类型断言 提供了访问接口值底层...
-
7
找出栈上的指针/引用 | HeapDump性能社区文章>找出栈上的指针/引用找出栈上的指针/引用RednaxelaFX
-
5
通过引用计数解决野指针的问题(C&C++) 浏览:3080次 出处信息 C/C++代码中,野指针问题历来已久,当然,大...
-
5
C++如何把字面量赋值给指针的引用?在vs2017中写了段C++: const char* p = "hello"; // 正确 const char* &p2 = "hello"; /…2
-
7
C++指针与引用小结C++指针与引用小结概念#
-
2
本文永久链接 – https://tonybai....
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK