我目前用这两种语言编程,而且我确实喜欢这两种语言--这是我最喜欢的两种编程语言,而且我觉得这两种语言都是我学习过程中的重要入门。
C#
有很多语法糖,虽然它可以(而且经常被)滥用,但可以减少很多操作的冗长性。尤其是开关表达式、三元操作符、模式匹配、空值检查和lambda表达式。
我喜欢Web APIs的内置模型绑定,它为你处理了很多模板转换和类型检查。
我喜欢许多东西可以用属性(Attributes)来标记,这些属性可以用来做各种事情,比如指定转换、验证等等。(go也有这个功能,但只适用于结构成员)。
泛型是非常强大的。
从坏的方面来说,C#应用程序的可移植性要差得多,因为你需要运行时和所有的依赖库来使你的应用程序工作。
当我试图为QA或其他团队成员制作工具时,我就被这个问题所困扰,因为他们从来没有安装过最新的运行时,而在Go中,我只需要给他们一个二进制文件。
在生态系统中,有很多不良的做法,这些做法源于对SOLID和 "模式 "编程的严格遵守,这些做法增加了更多的复杂性,而不是你用语言特性节省下来的,并且由于不断地在堆上喷射新的对象,到处都是虚拟调用,以及IEnumerable的缓慢延迟执行,而消耗了性能。
必须明确地写出async/await,这只是浪费时间。
LINQ是很好的,但是导致人们根本不考虑数据结构,导致很多性能不好的代码,并且有一些问题。
当用于网络编程时,通常你只是在缓慢的事物之间协调数据流,所以性能最终会足够快,不会成为瓶颈。
库和框架都是经过编译的,而且通常是闭源的,所以更难看到引擎盖下发生了什么,导致 "神奇 "的功能可能难以理解和调试。
C#有很多方法可以将复杂的功能隐藏在看似良性的操作背后,这可能会使性能的推理变得非常困难,也会让你对bug感到惊讶。
GO
我喜欢它对简单性的关注,以及更接近事物在较低层次的工作方式。
在Go上工作无疑帮助我更好地理解了一些概念,特别是 "引用类型 "到底是什么,因为 "引用 "是显式的,数据结构和分配如何影响性能,以及不同行为的成本。
我必须做不同的事情才能在Go中获得可读的代码,这一点我也能运用到其他语言中。
Go的理念通常会使代码更容易推理,更容易知道发生了什么,而且通常也更有性能。
该语言中的想法一般都非常优雅。Go库是开源的,所以很容易知道某些东西在做什么,并在出错时进行故障排除。
Go的网络库不支持一些在.Net中可以做到的语法特性,但仍然是完整的。
Go通常非常快,尽管我怀疑这很大程度上是由于语言的简洁性造成的,通常较少的LOC会导致较快的代码。
Go应用程序的可移植性很强,我甚至能够在Windows上可靠地构建Linux二进制文件。Async/await是自动的。
在缺点方面,Go似乎过于简单。
代码在有很多错误和/或条件的地方会变得相当冗长。
Go有一些语法糖的方式最终并不那么有用,例如,我几乎没有发现if
块中的额外语句能提高可读性。
错误处理比异常处理更直接,但通常比许多人认为的更冗长。
Go的一些选择是很奇怪的,比如它被作为一种系统语言来销售,但它限制了对系统apis和primitives的访问,不能真正用于系统编程,是垃圾收集的,有很少的本征,而且编译器不能很好地优化(没有自动矢量),所以不能用于 "真正的 "高性能软件(至少,如果不在ASM中写热循环)。
除了像C/C++这样的 "真正的 "系统语言外,它仍然比其他任何语言快得多,但我必须根据作者的说法来判断。
对惯例/结构的有限指导会使你很难知道你所做的事情是否 "好",但总的来说,我还是宁愿用结构不好的Go代码工作,而不是其他大多数语言。泛型也比C#的弱很多--这不一定是坏事,因为它们在有泛型的语言中经常被滥用。
在我自己的项目中,我一直选择Go,主要是因为在Go中工作时缺乏摩擦,但也因为我的个人目标是学习更多低级别的东西。Go绝对教会了我很多东西,虽然它不是一种 "完美 "的语言,但它是最好的语言之一,我绝对会向任何想要学习的人推荐它。
迁移经验
我们有一个小的开发团队,我们实际上把我们的API/Web堆栈从整个.Net 4.5/dotnet core 2.1/3迁移到Nuxt.JS + Golang。
我在旧的技术栈上工作了3年左右,新技术栈在生产中使用了3年左右。因此,我们有很多经验,知道什么是有效的,为什么我们要转移,以及我们现在的情况。
根据你的团队的使用情况,从C#/dotnet迁移会给你的工作增加一些复杂性。我不认为有一个明确的方法是最好的方法,真正的方法是你的团队感到舒适并喜欢用它来编写软件。
有些时候我很怀念dotnet的Razor页面/全SSR时代。我认为框架的编写方式非常简单,并为 "包括电池 "的哲学提供了价值。Golang的html/template库也很好,但有时会导致写更多的自定义代码,而这对于一个小企业来说是很难维护的。
在Go方面,我一般喜欢Go。我认为,只要你采用好的模式,并坚持一个计划来编写一致的代码,它的阅读和编写一样有趣。我对太多的编程语言没有这种感觉。
这两种语言都很容易进行单元测试,并且可以移植到各个地方使用(服务器、Lambda、CLI等)。两者都不会出错,因为到最后你会学到一些模式(Web服务器/HTTP/Rest/GraphQL,DB连接,CLI流程等),这些都与你选择的语言或框架无关。只要选择能给你带来最大快乐的那个,你就不会出错。