如何看待go语言泛型的最新设计?

发布网友 发布时间:2022-04-23 08:15

我来回答

15个回答

热心网友 时间:2022-04-19 04:21

Go 由于不支持泛型而臭名昭著,但最近,泛型已接近成为现实。Go 团队实施了一个看起来比较稳定的设计草案,并且正以源到源翻译器原型的形式获得关注。本文讲述的是泛型的最新设计,以及如何自己尝试泛型。

例子

FIFO Stack

假设你要创建一个先进先出堆栈。没有泛型,你可能会这样实现:

type Stack []interface{}func (s Stack) Peek() interface{} {

 

return s[len(s)-1]

}

func (s *Stack) Pop() {

 *s = (*s)[:

len(*s)-1]

}

func (s *Stack) Push(value interface{}) {

 *s = 

append(*s, value)

}

但是,这里存在一个问题:每当你 Peek 项时,都必须使用类型断言将其从 interface{} 转换为你需要的类型。如果你的堆栈是 *MyObject 的堆栈,则意味着很多 s.Peek().(*MyObject)这样的代码。这不仅让人眼花缭乱,而且还可能引发错误。比如忘记 * 怎么办?或者如果您输入错误的类型怎么办?s.Push(MyObject{})` 可以顺利编译,而且你可能不会发现到自己的错误,直到它影响到你的整个服务为止。

通常,使用 interface{} 是相对危险的。使用更多受*的类型总是更安全,因为可以在编译时而不是运行时发现问题。

泛型通过允许类型具有类型参数来解决此问题:

type Stack(type T) []Tfunc (s Stack(T)) Peek() T {

 

return s[len(s)-1]

}

func (s *Stack(T)) Pop() {

 *s = (*s)[:

len(*s)-1]

}

func (s *Stack(T)) Push(value T) {

 *s = 

append(*s, value)

}

这会向 Stack 添加一个类型参数,从而完全不需要 interface{}。现在,当你使用 Peek() 时,返回的值已经是原始类型,并且没有机会返回错误的值类型。这种方式更安全,更容易使用。(译注:就是看起来更丑陋,^-^)

此外,泛型代码通常更易于编译器优化,从而获得更好的性能(以二进制大小为代价)。如果我们对上面的非泛型代码和泛型代码进行基准测试,我们可以看到区别:

type MyObject struct {

    X 

int

}

var sink MyObjectfunc BenchmarkGo1(b *testing.B) {

 

for i := 0; i < b.N; i++ {

  

var s Stack

  s.Push(MyObject{})

  s.Push(MyObject{})

  s.Pop()

  sink = s.Peek().(MyObject)

 }

}

func BenchmarkGo2(b *testing.B) {

 

for i := 0; i < b.N; i++ {

  

var s Stack(MyObject)

  s.Push(MyObject{})

  s.Push(MyObject{})

  s.Pop()

  sink = s.Peek()

 }

}

结果:

BenchmarkGo1BenchmarkGo1-16     12837528         87.0 ns/op       48 B/op        2 allocs/opBenchmarkGo2BenchmarkGo2-16     284079         41.9 ns/op       24 B/op        2 allocs/op

在这种情况下,我们分配更少的内存,同时泛型的速度是非泛型的两倍。

合约(Contracts)

上面的堆栈示例适用于任何类型。但是,在许多情况下,你需要编写仅适用于具有某些特征的类型的代码。例如,你可能希望堆栈要求类型实现 String() 函数

热心网友 时间:2022-04-19 05:39



本文最初发布于 Go 语言官方博客,由 InfoQ 中文站翻译并分享。

近日,Go 语言社区正式发布 2019 年度调查报告,本次调研共收到 10975 份回复,几乎是 2018 年的两倍,以下是本次报告的重要内容。

重要结论

本文篇幅较长,希望快速了解结果的可以阅读如下概述:

调查对象的人口统计数据与 Stack Overflow 相似,因此这些结果代表了广泛的 Go 开发者;

大多数受访者每天都使用 Go,而且这个数量每年都在上升;

Go 的使用仍主要集中在科技公司,但也越来越多地出现在金融和媒体等行业;

通过调整方法,我们看到大多数年度同期指标都很稳定,并且高过我们之前的认知;

受访者使用 Go 解决的问题类似,特别是构建 API/RPC 服务和 CLI,而这与所在组织规模无关;

大多数团队都会设法更新当前 Go 语言的版本,当第三方提供商不能支持 Go 的当前版本时,就会妨碍开发人员采用;

在 Go 生态系统中,几乎每个人都在使用 Moles,但在包管理方面仍然存在一些混乱;

具有高优先级的改进项包括改进开发人员的调试体验、Moles 使用体验和云服务使用体验;

VS Code 和 GoLand 使用率持续上升,四分之三的受访者当下首选二者;

泛型依旧被认为是 Go 缺失的关键特性。

详细说明

2019 年,我们提出了一些新问题,以帮助更好地了解参与调查的人,比如从事编程的经验年限和所服务的组织规模,这些问题参考了 StackOverflow 的年度调查。我们也看到最终结果与 StackOverflow 2019 年的结果非常接近。我们的结论是,本次调查的受访者与 StackOverflow 的受访者经验水平类似,而且不同规模的组织比例也相似(差别是我们的调查对象是 Go 开发人员)。

所在组织规模
根据调查,大部分受访者所在公司的人数规模在 1000 人以下,且其中有 65% 的受访者具备 10 年以下编程经验。

从事编程工作(或编程作为工作的一部分内容)的时间
Go 开发者相对较新,半数经验不足两年

从结果来看,大多数受访者(56%)都是相对较新的 Go 开发者,他们使用 Go 还不到两年。另外,72% 的受访者在工作时间使用 Go

热心网友 时间:2022-04-19 07:14

目前,为实现泛型的需求,在Go语言中往往有如下几种方式1[1]:

1.Interface (with method) 优点:无需三方库,代码干净而且通用。 缺点:需要一些额外的代码量,以及也许没那么夸张的运行时开销。2.Use type assertions 优点:无需三方库,代码干净。 缺点:需要执行类型断言,接口转换的运行时开销,没有编译时类型检查。3.Reflection 优点:干净 缺点:相当大的运行时开销,没有编译时类型检查。4.Code generation 优点:非常干净的代码(取决工具),编译时类型检查(有些工具甚至允许编写针对通用代码模板的测试),没有运行时开销。 缺点:构建需要第三方工具,如果一个模板为不同的目标类型多次实例化,编译后二进制文件较大。
betterGo就是通过code generation来实现泛型

如何使用

如果你想使用betterGo来通过自动生成代码的方式实现泛型,可以看下面的例子:

在项目中包含了测试用例,例如,需要使用泛型的代码是test/map/map.go,如果想用interface{} 的函数就是enum.Map 这样子用。

如果想生成具体类型的函数,就运行这行命令:go run main.go -w -f test/map/map.go

然后你发现 test/map/map.go 改变了,enum.Map 变成了: enum.MapOriginFn(origin, fn)

然后你看项目目录下生成了: utils/enum/map.go,就是具体类型的函数

参与项目

如果想和我们一起完成项目的开发,可以直接看代码,然后看到ast相关的包,就简单进去看看,猜猜什么意思,应该就可以理解这个项目以及代码了。

如果想从理论出发的话,可以简单看看这本书:https://github.com/chai2010/go-ast-book ,其实他也就是把 ast 包里的代码简单讲讲。

想参与具体开发的话,又没有想改进的地方,可以看看项目接下来的TODO List

热心网友 时间:2022-04-19 09:05

1、学习曲线容易

Go语言语法简单,包含了类C语法。因为Go语言容易学习,所以一个普通的大学生花几个星期就能写出来可以上手的、高性能的应用。在国内大家都追求快,这也是为什么国内Go流行的原因之一。
2、效率:快速的编译时间,开发效率和运行效率高

开发过程中相较于 Java 和 C++呆滞的编译速度,Go 的快速编译时间是一个主要的效率优势。Go拥有接近C的运行效率和接近PHP的开发效率。
3、出身名门、血统纯正

之所以说Go出身名门,从Go语言的创造者就可见端倪,Go语言绝对血统纯正。其次Go语言出自Google公司,Google在业界的知名度和实力自然不用多说。Google公司聚集了一批牛人,在各种编程语言称雄争霸的局面下推出新的编程语言,自然有它的战略考虑。而且从Go语言的发展态势来看,Google对它这个新的宠儿还是很看重的,Go自然有一个良好的发展前途。
4、自由高效:组合的思想、无侵入式的接口

Go语言可以说是开发效率和运行效率二者的完美融合,天生的并发编程支持。Go语言支持当前所有的编程范式,包括过程式编程、面向对象编程、面向接口编程、函数式编程。程序员们可以各取所需、自由组合、想怎么玩就怎么玩。

5、强大的标准库

这包括互联网应用、系统编程和网络编程。Go里面的标准库基本上已经是非常稳定了,特别是我这里提到的三个,网络层、系统层的库非常实用。Go 语言的 lib 库麻雀虽小五脏俱全。Go 语言的 lib 库中基本上有绝大多数常用的库,虽然有些库还不是很好,但我觉得不是问题,因为我相信在未来的发展中会把这些问题解决掉。

6、部署方便:二进制文件,Copy部署

这一点是很多人选择Go的最大理由,因为部署太方便了,所以现在也有很多人用Go开发运维程序。

热心网友 时间:2022-04-19 11:13

像 C# 和 Java 也可以使用 unsafe 来访问更底层,而高级封装,Go 语言只是抽象了一些用 C 实现起来特别繁重,坑特别多的东西.就像 slice 简化了对数组的操作和处理,而 channel 什么的,让实现并发逻辑简洁又高效,让程序员可以有更多精力聚焦业务逻辑的设计,而不是关心这个锁,那个锁.但要说到语言设计的优劣,Go语言确实没太多亮点.特别是处理数据库数据和 JSON类似的数据还是和其他强类型语言一样,麻烦又繁琐.
但在工程上,或者实际项目上,它有无可匹敌的几大优势:
1. 容易部署,比任何一种能胜任商业项目的语言都要简单,干练.
2. 由于语言设计的硬性规则,让执行一套辅助开发的工具,更好实现.比如代码格式化,代码分析.(虽然有点没人性,但很适合发挥团队效益)
3. 也因为硬性规则,编译时间特别快.
4. 也因为硬性规则,单元测试起来也很方便,基本可以实现边写边测.这种特性有时候很有用.
5. 因为编译时间快和部署的相对简单,它也能像动态语言一样,做一些类似脚本的工作.不需要像 Java 和 C# 一样,做点小事情,也要一个硕大的运行库,什么都要正规正矩的设计几个接口,不然重用起来很难.
再者很少有大项目,不需要或多或少的触碰一下底层来突破性能瓶颈,或者加速项目开发的.
比如说在 Go 语言里, 可以用 unsafe.Pointer(不需在内存上拷贝数据) 在 []byte 和 string 之间进行转换.
总而言之,Go 语言是一种进可攻退可守的语言.可以偏向效率的很快开发一个项目,可以为了性能,不断的优化数据结构,不断的开发硬件的性能.

热心网友 时间:2022-04-19 13:38

大部分吐糟都在表示这种设计本着原来很成熟的<>方案不用,分要发明自己的(), 看起来不好看、怪异~~~ 不过我觉得这种设计还是蛮好的,为什说好呢,因为人家本来就不是奔着 <> 去的。

在 java/C#/C++ 中,使用 <> 语法给人的直观感觉是这是一种约定或者是对函数/类的装饰,这种约定让一个方法具备了泛型能力。粗看之下 Go 是把 <> 换成了 () 所以语法顿时变得怪怪的~~~

但是,在 Go 的这种设计中这压跟就不是<>语法的约定/装饰的意义,人家就是一个踏踏实实的方法,你调用 Foo(int, int) 的时候其实就是调用一个泛型方法,传入的是类型参数、返回的是具体类型的方法,这么一看豁然开朗~~ 而且特别容易理解和使用。

比如我们可以写这样的语句:
func IntAbs = math.ABS(int);
func FloatAbs = math.ABS(float);
而在其它语言中(比如Java/C#),你肯定不能写:
IntAbs = math.Abs<int>
当然在实际使用中,编译器会自动推导出类型,所以使用的时候大多我们是可以直接用 而不是
a个人还是挺喜欢 Go 的这个设计的,非常的平滑没有对之前的东西造成破坏,而且还有一定的想象空间,如果以后类型也能变成可计算、可编程的,那么 Go 语言将能实现更多复杂的功能,而且它的实现成本非常非常的低。

Java和C#的泛型设计都是一个路子采用 <> 的设计,这种设计我以前用的也是蛮多的,这是一种约定式的语法,这种语法在简单场景下还是挺好用的,但是在复杂场景下代码的可读性会非常差。Go 语言其实提供了一种完全不一样的路子,不约定而是创造,这种思路让你看到了泛型的实现过程同时保持了很高的灵活性,个人觉得还是很符合 Go 的大道至简的信条的~~

热心网友 时间:2022-04-19 16:19

像 C# 和 Java 也可以使用 unsafe 来访问更底层,而高级封装,Go 语言只是抽象了一些用 C 实现起来特别繁重,坑特别多的东西.就像 slice 简化了对数组的操作和处理,而 channel 什么的,让实现并发逻辑简洁又高效,让程序员可以有更多精力聚焦业务逻辑的设计,而不是关心这个锁,那个锁.但要说到语言设计的优劣,Go语言确实没太多亮点.特别是处理数据库数据和 JSON类似的数据还是和其他强类型语言一样,麻烦又繁琐.
但在工程上,或者实际项目上,它有无可匹敌的几大优势:
1. 容易部署,比任何一种能胜任商业项目的语言都要简单,干练.
2. 由于语言设计的硬性规则,让执行一套辅助开发的工具,更好实现.比如代码格式化,代码分析.(虽然有点没人性,但很适合发挥团队效益)
3. 也因为硬性规则,编译时间特别快.
4. 也因为硬性规则,单元测试起来也很方便,基本可以实现边写边测.这种特性有时候很有用.
5. 因为编译时间快和部署的相对简单,它也能像动态语言一样,做一些类似脚本的工作.不需要像 Java 和 C# 一样,做点小事情,也要一个硕大的运行库,什么都要正规正矩的设计几个接口,不然重用起来很难.
再者很少有大项目,不需要或多或少的触碰一下底层来突破性能瓶颈,或者加速项目开发的.
比如说在 Go 语言里, 可以用 unsafe.Pointer(不需在内存上拷贝数据) 在 []byte 和 string 之间进行转换.
总而言之,Go 语言是一种进可攻退可守的语言.可以偏向效率的很快开发一个项目,可以为了性能,不断的优化数据结构,不断的开发硬件的性能.像 C# 和 Java 也可以使用 unsafe 来访问更底层,而高级封装,Go 语言只是抽象了一些用 C 实现起来特别繁重,坑特别多的东西.就像 slice 简化了对数组的操作和处理,而 channel 什么的,让实现并发逻辑简洁又高效,让程序员可以有更多精力聚焦业务逻辑的设计,而不是关心这个锁,那个锁.但要说到语言设计的优劣,Go语言确实没太多亮点.特别是处理数据库数据和 JSON类似的数据还是和其他强类型语言一样,麻烦又繁琐.但在工程上,或者实际项目上,它有无可匹敌的几大优势:1. 容易部署,比任何一种能胜任商业项目的语言都要简单,干练.2. 由于语言设计的硬性规则,让执行一套辅助开发的工具,更好实现.比如代码格式化,代码分析.(虽然有点没人性,但很适合发挥团队效益)3. 也因为硬性规则,编译时间特别快.4. 也因为硬性规则,单元测试起来也很方便,基本可以实现边写边测.这种特性有时候很有用.5. 因为编译时间快和部署的相对简单,它也能像动态语言一样,做一些类似脚本的工作.不需要像 Java 和 C# 一样,做点小事情,也要一个硕大的运行库,什么都要正规正矩的设计几个接口,不然重用起来很难.再者很少有大项目,不需要或多或少的触碰一下底层来突破性能瓶颈,或者加速项目开发的.比如说在 Go 语言里, 可以用 unsafe.Pointer(不需在内存上拷贝数据) 在 []byte 和 string 之间进行转换.总而言之,Go 语言是一种进可攻退可守的语言.可以偏向效率的很快开发一个项目,可以为了性能,不断的优化数据结构,不断的开发硬件的性能.

热心网友 时间:2022-04-19 19:17

像 C# 和 Java 也可以使用 unsafe 来访问更底层,而高级封装,Go 语言只是抽象了一些用 C 实现起来特别繁重,坑特别多的东西.就像 slice 简化了对数组的操作和处理,而 channel 什么的,让实现并发逻辑简洁又高效,让程序员可以有更多精力聚焦业务逻辑的设计,而不是关心这个锁,那个锁.但要说到语言设计的优劣,Go语言确实没太多亮点.特别是处理数据库数据和 JSON类似的数据还是和其他强类型语言一样,麻烦又繁琐.
但在工程上,或者实际项目上,它有无可匹敌的几大优势:
1. 容易部署,比任何一种能胜任商业项目的语言都要简单,干练.
2. 由于语言设计的硬性规则,让执行一套辅助开发的工具,更好实现.比如代码格式化,代码分析.(虽然有点没人性,但很适合发挥团队效益)
3. 也因为硬性规则,编译时间特别快.
4. 也因为硬性规则,单元测试起来也很方便,基本可以实现边写边测.这种特性有时候很有用.
5. 因为编译时间快和部署的相对简单,它也能像动态语言一样,做一些类似脚本的工作.不需要像 Java 和 C# 一样,做点小事情,也要一个硕大的运行库,什么都要正规正矩的设计几个接口,不然重用起来很难.
再者很少有大项目,不需要或多或少的触碰一下底层来突破性能瓶颈,或者加速项目开发的.
比如说在 Go 语言里, 可以用 unsafe.Pointer(不需在内存上拷贝数据) 在 []byte 和 string 之间进行转换.
总而言之,Go 语言是一种进可攻退可守的语言.可以偏向效率的很快开发一个项目,可以为了性能,不断的优化数据结构,不断的开发硬件的性能

热心网友 时间:2022-04-19 22:32

哇。。。要不要专门点我嘛。。。
其实按照如意金箍棒,它的控制指令词语就五个:长短粗细停。衍生出来的什么快一点、慢一点、够了(性情乱入)。PS:楼下自重啊~我说的是变长得快一些~;这些词语好在不复杂、不算多,可以早期就编写进去。短词语的识别度高,数量少也能保证不会误识别~
语音识别要提取出来这几个词语也不难。
稍微麻烦的可能是专人专用,这个建立一个语音库的那啥来着。。。。每个人发音的音色、频率都不一样,不过现在仿佛也有声纹识别的。每个人的声音甚至像指纹一样是独有的哦~
脑电波这个玩意目前的设备还不能太小,而孙悟空那个的头箍又是在金箍棒之后赠送的。要我看,可能连语音识别都不太算,悟空可以捏住金箍棒的某个部位,让它变长变硬(感觉有点不对劲~),压力传感器就比语音识别好做多了。
以上都是在电的范围内的,接下来到了材料,我记得压电晶体可以把电信号转换成机械振动的~那么其实材料也不远的~通电就伸、缩什么的~
材料不是我管的范围~术业有专攻哦也~有人做出了材料可以寻求合作。。。
不过。。。魔术用的伸缩匕首算不算??如果伸缩不考虑高科技。。。伸缩晾衣杆什么的~

16

热心网友 时间:2022-04-20 02:03

像 C# 和 Java 也可以使用 unsafe 来访问更底层,而高级封装,Go 语言只是抽象了一些用 C 实现起来特别繁重,坑特别多的东西.就像 slice 简化了对数组的操作和处理,而 channel 什么的,让实现并发逻辑简洁又高效,让程序员可以有更多精力聚焦业务逻辑的设计,而不是关心这个锁,那个锁.但要说到语言设计的优劣,Go语言确实没太多亮点.特别是处理数据库数据和 JSON类似的数据还是和其他强类型语言一样,麻烦又繁琐.
但在工程上,或者实际项目上,它有无可匹敌的几大优势:
1. 容易部署,比任何一种能胜任商业项目的语言都要简单,干练.
2. 由于语言设计的硬性规则,让执行一套辅助开发的工具,更好实现.比如代码格式化,代码分析.(虽然有点没人性,但很适合发挥团队效益)
3. 也因为硬性规则,编译时间特别快.
4. 也因为硬性规则,单元测试起来也很方便,基本可以实现边写边测.这种特性有时候很有用.
5. 因为编译时间快和部署的相对简单,它也能像

热心网友 时间:2022-04-20 05:51

我觉得最应该说就是go语言的goroutine,这个机制使得该语言特别适合于网络编程和io较多的场景,它从编程语言层次很好解决了多线程编程的难点,比如传统线程内存消耗大,编程难度高等问题。在go语言精心的设计下,我这种小白也可以整天大刀阔斧的多线程编程了,难度真的降了好几个数量级。

再着,我喜欢它独特的编程模式。他抛弃了大多数面向对象语言的那种声明类的语言,采用结构体加方法的形式组织类型。这使得该语言倾向于”不伦不类”,它既有面向对象语言的特点,又有面向过程需要的特点,我相信这样的结果正恰恰是go语言设计者的初衷。他们都是有着丰富的编程经验的世界级工程师,他们对此有着自己深刻的认识以及经验。因此,他们将语言设计为这样。

其中有一个让我拍案叫绝的小设计是,它们去掉了无用的while循环,直到这里,我才明白了代码到底可以多简单,这么多年的while语句原来是废物,它们只是让一门语言变得更加复杂而已。

最后,go语言真的值得一学!

热心网友 时间:2022-04-20 09:56

package main

import (
"fmt"
)

type NewStringHelper (type T) interface {
Test() T
ToString() string
}

type NewStringTImpl struct {
v string
}

func (t NewStringTImpl) Test() NewStringTImpl {
return t
}

func (t NewStringTImpl) ToString() string {
return t.v
}

type NewStringTImpl2 struct {
v string
}

func (t NewStringTImpl2) Test() string {
return t.v
}

func (t NewStringTImpl2) ToString() string {
return t.v
}

func test(type T NewStringHelper(T))(t T) string{
return t.Test().ToString()
}

func test2(type U)(t NewStringHelper(U)) U{
return t.Test()
}

type NewStringTImpl3(type T) struct {
v T
}

func (t NewStringTImpl3(T)) Test() T{
return t.v
}

func (t NewStringTImpl3(T)) ToString() T{
return t.v
}

func test3(type U)(t NewStringTImpl3(U)) U{
return t.Test()
}

func main() {
fmt.Print(test(NewStringTImpl{"test"}))
//fmt.Print(test2(NewStringTImpl{"test"}).ToString())
fmt.Print(test2(NewStringTImpl)(NewStringTImpl{"test"}).ToString())
t3 := test2(NewStringTImpl)
fmt.Print(t3(NewStringTImpl{"test"}).ToString())
//fmt.Print(test2(NewStringTImpl2{"test"}))
fmt.Print(test2(string)(NewStringTImpl2{"test"}))
//fmt.Print(test2(NewStringTImpl3(string){"test"}))
fmt.Print(test2(string)(NewStringTImpl3(string){"test"}))
fmt.Print(test3(NewStringTImpl3(string){"test"}))
}
玩了一下还可以,因为Golang的特性,所以可以像上面的例子一样,约束某个输出参数返回自身,虽然不是很显然。不支持main里面注释掉的第二行那样通过一个泛型类型接口推断出泛型参数(也能想象)

实验表明目前的泛型推断仅限于类型精确匹配的场景,不适用于类型声明为泛型interface的场景。例如例子里面的最后一个test3是可以推断的,但前面两个test2则必须要指定泛型参数才能编译成功。说明类型推断用的是比较简单的实现方式。

热心网友 时间:2022-04-20 14:17

1. 大道至简
就多了两个概念,类型参数(type parameter)和约束(constraint)。十分钟学完,其它没有了;学不会你找我。
类型参数
无约束函数 func F(type T)(p T) { ... }
有约束函数 func F(type T Constraint)(p T) { ... }
以上同样也适用于类型 type M(type T) []T
约束
其实就是一个可以塞类型的interface
type SignedInteger interface {
type int, int8, int16, int32, int
}
去掉了计划中引入的关键词contract,使得Go的关键词数量保留25个。
2. 类型推断
节省了很多代码和程序员时间
package slices
func Map(type T1, T2)(s []T1, f func(T1) T2) []T2 {
r := make([]T2, len(s))
for i, v := range s {
r[i] = f(v)
}
return r
}
照理说应该
s := []int{1, 2, 3}
floats := slices.Map(int, float)(s, func(i int) float { return float(i) })
但是有了类型推断黑科技,就简单多了
floats := slices.Map(s, func(i int) float { return float(i) })
对struct也一样
type Pair(type T) struct { f1, f2 T }
var V = Pair{1, 2} // inferred as Pair(int){1, 2}
3. 玩法多样
随用随走。想用特定的类型和函数,简单,开头定义一下就好了。

热心网友 时间:2022-04-20 18:55

Copyright 1999-2020, CSDN.NET, All Rights Reserved
登录
为什么 Go 语言没有泛型 · Why's THE Design? 转载
2020-02-01
Go中国
码龄3年
关注
为什么这么设计(Why’s THE Design)是一系列关于计算机领域中程序设计决策的文章,我们在这个系列的每一篇文章中都会提出一个具体的问题并从不同的角度讨论这种设计的优缺点、对具体实现造成的影响。如果你有想要了解的问题,可以在文章下面留言。
Go 是一门语法元素少、设计简单的编程语言,简单的设计往往意味着较弱的表达能力,工程师也需要使用更多时间编写重复的逻辑。Go 语言从发布到今天已经过去了 10 多年,向 Go 语言添加泛型的讨论也从 2010 年一直持续到今天。社区对泛型的讨论非常多,呼声也非常高,下这里列举一些泛型相关的讨论和反馈:
proposal: spec: generic programming facilities 有 500 多条泛型相关的讨论[^1];
Generics · ExperienceReports 列出了一些讨论 Go 语言泛型的文章[^2];
Go 2 Generics Feedback 包含对 Go 2 泛型草案的反馈和建议[^3];
很多人都认为 Go 语言永远不会加入泛型,然而这不是正确的结论,Go 语言很可能会在第二个主要版本中加入泛型[^4]。所以本文要分析的问题是 —— 为什么 Go 语言到目前为止都没有泛型,以及这些原因是否已经被解决,又是如何被解决的。

热心网友 时间:2022-04-20 23:50

这是关于 「Go是一门设计糟糕的编程语言 (Go is not good)」 系列的另一篇文章。Go 确实有一些很棒的特性,所以我在这篇文章中展示了它的优点。但是总体而言,当超过 API 或者网络服务器(这也是它的设计所在)的范畴,用 Go 处理商业领域的逻辑时,我感觉它用起来麻烦而且痛苦。就算在网络编程方面,Go 的设计和实现也存在诸多问题,这使它看上去简单实际则暗藏危险。
写这篇文章的动机是因为我最近重新开始用 Go 写一个业余项目。在以前的工作中我广泛的使用了 Go 为 SaaS 服务编写网络代理(包括 http 和原始的 tcp)。网络编程的部分是相当令人愉快的(我也正在探索这门语言),但随之而来的会计和账单部分则苦不堪言。因为我的业余项目只是一个简单的 API,我认为 Go 非常适合快速的完成这个任务。但是我们都知道,很多项目的增长会超过了预期的范围,所以我不得不写一些数据处理来计算统计数据,Go 的痛苦之处也随着而来。下面就是我对 Go 的困扰。

声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com