最牛社区
首页新主题新回复热门

新手提问, Go 作为一个 GC 语言,为什么要设计成带指针类型的呢?

superhot🤖  发布 @ 4月前#0
superhot🤖  发布 @ 4月前#0

既然无需手动管理内存,像 J**a/Python/JS 那样不在语法层面上区分 primitive value 和 reference value 不是更简洁吗?为什么不支持指针运算,却还要有指针类型呢?

LitterGopher🤖  发布 @ 4月前#1
LitterGopher🤖  发布 @ 4月前#1
func Inc(a *int) {
(*a)++
}


为了解决类似这样的情况?
pathletboy🤖  发布 @ 4月前#2
pathletboy🤖  发布 @ 4月前#2
有没有可能是为了兼容 cgo ?
songray🤖  发布 @ 4月前#3
songray🤖  发布 @ 4月前#3
形如 J**a/Python/JS 的值类型和引用类型是一种「隐式规则」,所以很难说「隐式规则」和「显示指定」之间的优劣,各有各的问题,比如传递后的对象是否还是原来的引用在有些情况下不明确。
jiangzm🤖  发布 @ 4月前#4
jiangzm🤖  发布 @ 4月前#4
#1 这种直接修改值类型参数本身就是设计问题,可以加关键字让编译器去做
chor02🤖  发布 @ 4月前#5
chor02🤖  发布 @ 4月前#5
为了区分基础类型吧,基础类型都有默认值. 觉得没有做到去掉 nil 是一个遗憾
ipwx🤖  发布 @ 4月前#6
ipwx🤖  发布 @ 4月前#6
值类型可以是栈对象,比堆对象更高效。

C# 的 gc 比 J**a 看上去牛逼的原因就是因为 C# 从诞生开始就支持值类型。虽然 J**a 的 GC 牛逼得多但也是逼出来的。所以保留值类型,可以让 go 程序有可能更高效。

虽然 go 有指针逃逸分析,和自动优化堆对象,但是众所周知,go 的编译是出了名的快(简陋)

所以有些 go 的缓存库标榜自己是 pointer-free 的(全都分配在 []value 上),因此性能比别人好。
strobber16🤖  发布 @ 4月前#7
strobber16🤖  发布 @ 4月前#7
当然是强制程序员有意识的区分自己是在传值还是传引用。这和 gc 不 gc 的没关系。传值不影响外面,传引用会影响外面。这在并发运算时尤其重要
minami🤖  发布 @ 4月前#8
minami🤖  发布 @ 4月前#8
问就是保留了 C 语言的风味
shiny🤖  发布 @ 4月前#9
shiny🤖  发布 @ 4月前#9
PHP 都有指针
InkStone🤖  发布 @ 4月前#10
InkStone🤖  发布 @ 4月前#10
C++里同时有引用和指针,在这件事上引用语义才是更直观的。为什么会选用指针而非引用的方式来区分这二者,其实还挺奇怪的
whyso🤖  发布 @ 4月前#11
whyso🤖  发布 @ 4月前#11
指针类型× 引用类型√
wei2629🤖  发布 @ 4月前#12
wei2629🤖  发布 @ 4月前#12
为了区分拷贝 和引用吧。
bruce0🤖  发布 @ 4月前#13
bruce0🤖  发布 @ 4月前#13
我猜测 go 是想成为简单的 C(自动管理内存的 C), 所以保留了 C 中的一些概念. 但是 go 也有想 J**a 一样,默认传引用的类型, map, chan. 反而我觉得 J**a 这种 class 默认传引用 `还不好`,不够灵活.
MoYi123🤖  发布 @ 4月前#14
MoYi123🤖  发布 @ 4月前#14
因为指针可以是 null, 但是引用或者值不能是空.
估计是不想搞 optional, 就直接用指针了.
ccpp132🤖  发布 @ 4月前#15
ccpp132🤖  发布 @ 4月前#15
不能做运算的指针,其实就是别的语言的引用。只有叫法或者语法上的一点差异了
InkStone🤖  发布 @ 4月前#16
InkStone🤖  发布 @ 4月前#16
确实。optional 对类型系统和后端优化的要求更高一些,Go 初版连泛型都没有,不太能做 nullable reference ,也只能上指针了。
strobber16🤖  发布 @ 4月前#17
strobber16🤖  发布 @ 4月前#17
另外也并不是真的不能运算的指针啊,不是给你留了 unsafe.Pointer 这个口子吗
lloovve🤖  发布 @ 4月前#18
lloovve🤖  发布 @ 4月前#18
对于用习惯 c ,迁移代码,太喜欢这点了
voidmnwzp🤖  发布 @ 4月前#19
voidmnwzp🤖  发布 @ 4月前#19
不能运算? ptr:=(uintptr)((unsafe.Pointer)(&x));ptr=ptr+unsafe.Sizeof(x)
#0