欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  后端开发

一个 Python 初学者应该如何在 Rust 和 Go 之间选择?

程序员文章站 2022-06-13 11:05:26
...
已经学了一段Python,喜欢他的风格。像库概念,变量定义,编程风格都喜欢。
对指针概念不太理解,C++停留在大一上的VC6.0时代。

想再学一门快速编译型的语言。哪位能比较一下Rust和Go,根据以上内容推荐一个。(比较内容详细点更好)

回复内容:

自己花时间学下,就有能力比较了。
tour.golang.org/#

The Rust Guide

rust没有runtime,go有runtime,所以同样的工作比如内存管理,rust倾向于在编译期做,go倾向于在运行期做。这都是和他们最初的目的相符的,rust用于写浏览器,需要性能,go用于写网络服务的服务器端,runtime强点线上调试起来也方便。虽然都是通用型语言,但是是有倾向有侧重的。
这都是我个人的看法,其他人可能觉得这种区别没什么意义。花括号能否独立做一行,有没有泛型,好不好学,库多不多,他们可能认为这些比较重要。
所以比较两个语言这种事,还是自己做功课吧。python和这两个语言差别都很大,没有参考性。 利益相关:一年前就开始使用Go,Rust是从0.9-dev开始使用到现在0.13-dev。

Go本质上与C没有太大的区别,它的Runtime实际上就是wrap了一下libc,然后在语法层面提供了各种语法糖。但是它写起来比C舒服多了,类型推导、多返回值、interface、GC等等的特性,会让有Python经验的人觉得异常的亲切。不过话说回来,Go和Python是没办法拿来比较的,在长期使用之后会更加发现出两者的不同。

Rust目前还在dev阶段,据说年底beta,语法还在变动,下面所有的说法都基于0.13-dev。Rust如果与Go比较,可以类比成C++与C的比较(不严谨)。
1. Rust没有Runtime,所有的内存管理都在编译期完成。在Rust中比较突出的一个特性就是「Lifetime 生存期」,它就是编译器用来管理某个Object从构造到析构整个过程,因此在编译期就可以做到内存管理,避免开发者手动管理内存,也避免了内存泄露。虽然这种方法听起来觉得非常的完美,从0.9-dev到0.13-dev这段时期,生存期管理也变得更加智能和人性化,不过真的遇到编译器无法推测对象的生存期需要你手动去指定的时候,老实说对不熟悉的人来说也是非常的伤脑筋。
2. Rust对代码的安全性要求非常的高,从语法上规定了各种的约束(比如一个变量不能被borrow as mutable多于一次等),可以让编译器在编译时就帮你找出一些可能会出现Bug的点,然后编译失败逼你去把代码改成更安全的写法,编译器的要求可谓非常的严格,初学者基本就是每写一段代码就跪着问rustc到底对不对,和跪着问Google到底我为什么我写错了。在学Rust的这段时间里,Rust编译器纠正了我许多不好的编程习惯和教会了写代码要先全面地考虑(不然编译不过)。这种特性也让Rust实现了它宣传语中的那句话:prevents almost all crashes*, and eliminates data races
3. Rust写同样的一段程序跑得比Go要快,甚至有测试显示它的速度已经达到了Java的级别。(测试是在Hacker News上看到了,找到之后放上来)。
4. Rust编译目前远没有Go那么快。
5. Go有自带的goroutine,是轻量级的线程,而Rust在目前的版本已经从标准库移去了rustuv,默认使用Native thread来实现异步,使用起来和goroutine一样方便,相关的讨论可以在Hacker News上找到,The Rust standard library no longer has any scheduling baked into it。两者都有builtin的channel用于实现同步。(备注:Rust从标准库中移去了rustuv不代表它不支持green thread,而是选择了把EventLoop的实现交给社区,标准库只做接口,Scheduler rewrite with I/O event loop · Issue #4419 · rust-lang/rust · GitHub,默认标准库中的EventLoop不支持I/O)。
6. 讲到Rust不得不提它的Pattern matching,实在太过强大难以言表,请有兴趣的人去看一下Rust的文档相关的部分。据说源自Haskell。

对比Go和Rust,我的选择是Rust。但是它们和Python都相差挺大,Python的使用经验在这两门语言中的可复用性不算太大。
最近用Rust写了一个*-rust: zonyitoo/*-rust · GitHub,欢迎喜欢的同学一起来交流。 学会一门需要 200 个小时,两门总共需要 400 个小时,占你的总资产的(每天8小时,每年365天,70年,总计204400小时)的 0.2%

所以,买买买,两门都学就好了。

好像是 PG 的《On Lisp》的说法,决定你是否学习一门语言要取决于这门语言能否教给你新的思维方式。从这个角度来说,对 Python 背景的人,Go 和 Rust 都是很好的选择。



说一下题主提的这几样:


  • 库概念:Rust 合格,Go 合格。它们的模块管理方式都和 Python 类似,Go 更像 Python,Rust 的管理方式在清晰、易管理的同时更灵活。
  • 变量定义:Rust 和 Go 都是静态类型的,它们有各自的方法避免你*于强静态类型的限制而打太多字。Go 的类型体系都是线条型的,靠类型推导就可以避开局部变量的显式类型声明,除非你要用 type assert 把 interface 类型转为具体类型,或者把具体类型转为 interface 类型。Rust 相比之下有一个丰富的类型系统,它需要更聪明的 HM 推导系统来确定变量的类型,这就导致一种风格是你先不指定具体类型,等编译器提示某些值的类型它无法确定你再补上相应的类型声明。总的来说它们的打字的强度是接近的(除非你想用泛型做高层次的抽象,那么这些更泛用的代码自然会比对应版本的完全没有抽象的代码的量多一些,不过这种情况下 Go 没有对应物因为 Go 没法做泛型编程)。
  • 编程风格:Go 和 Rust 喜欢一定程度的透明性,要写出高效的代码而不要去做过度抽象。所以 Rust 和 Go 的抽象都是着手于概念。Go 是用 interface 表达概念,例如 io.Writer;Rust 用 trait 表达概念例如 std::iter::Iterator。除去概念,它们的手法都是编写一些不同形式的用于操纵数据的函数。没有类,只有裸的数据,而在思维上这些概念是和函数绑定的而不是和数据绑定的。数据封装是利用库之间的变量、类型、函数的可见性 。Rust 的 trait 有静态派发和动态派发两类场合,动态派发基于指针、虚函数表;静态派发基于泛型。Go 的 interface 仅限于动态派发,它依赖于指针和反射。

这里有个 C++、D、Rust、Go 放一起讨论的娱乐向视频:Panel: Systems Programming in 2014 and Beyond,讨论者都是四种语言自己的主力设计者(BS、D的维护者、Niko、Pike)。


上面谈到程序设计方面的风格,我说一下命名方面的风格:


  • Go 没有风格指南,但它都是用的是一种 CamelCase 驼峰风格来命名函数和类型。主要是按照 C 的习惯称呼一些老概念,根据这些来适配成驼峰风格。由于没有风格指南,凡事都有例外,比如 Go by Example: Structs 就采用全小写不加下划线的风格。
  • Rust 有个风格指南,项目在这里,可以从这里浏览。类型名采用驼峰风格,函数采用传统的 C 家族风格,snake_case。这个选择刚好和 Python 的 PEP8 一致,相信会让你感到愉快。
我们学习语言的目的是什么?解决项目的问题和解决生活的问题。

那么我们从两反面来看这个问题,第一项目的问题,Go和rust都是静态编译类型的语言,性能来说我之前看过对比,rust的更好一点,但是复杂度也是rust会更高,从我的角度来说,复杂度增加我是不能接受的,我需要一个简单的语法,让后面的维护变得容易,而这个性能的差距直接可以忽略,而且Go的版本发布稳定有序,Go目前最大的问题就是GC和泛型,泛型估计是不会解决了,GC的话目前来看已经解决的不错了,1.5版本解决GC问题。当然两个语言都学习一下也是不错的,学习两种语言的解决方案,就像 @李道兵说的两个都学习一下也不会浪费你多少时间。

第二个生活的问题,golang和rust招聘岗位,可以去各大招聘网站看看,rust有招聘的吗?golang有招聘的吗?现有大型公司更加偏向golang还是rust,这个公开的资料你都可以搜索的到,很显然的是golang各大公司都在使用,主要是docker的成功,成为了golang语言的第一个killer应用,很多公司使用docker作为他们接下来的部署系统。同时各个公司也使用golang开发了很多成功的系统。我相信会越来越多的公司招聘golang工程师,话说我最近就在招聘,新加坡Go工程师,新加坡公司招聘Go工程师 欢迎各位有志之士来人肉*啊 我是从Java两年转python两年转go一年,用过Java的感觉是框架好多好难学,而且一种框架忽然有一天升完级后我傻眼了(和上一个版本完全变样了),精力全耗在追逐框架上了。在Ruby如日中天的时候我也决定试一下动态语言,对比了Ruby和Python后,我喜欢上Python的中规中矩的语法和它超级丰富的库,我觉得找到了真爱,她让我和Java分手后有了很多惊喜:哇,语法超简单,我以前和Java说十句,和她说一句就明白,沟通(开发)效率提升十倍诶;哇,学一周就可以做项目了,你太单纯了;哇,web效率比Java快好多呀;我以为我们会相伴终身,可是相处久了越来越觉得对方的缺点不可容忍:运维部署好烦,Windows上开发完放到Linux上所有的关联库重新下载。满世界的语言好多支持多核并发时,她因为 JIT锁只能用multiprocessing处理,这个库效率低又得又主进程控制,主一出问题全线崩。一年半前我遇到了go,她优雅的气质一下就把我迷住了:哇,她可以把开发好的程序和关联库直接跨平台传;哇,她竟然可以直接编译机器码传到生产机执行;哇,她的语法和Python一样简单而且类似,我以前的代码基本没费多少功夫她就全部接管了;哇,她的指针可以让我实现以前不能直接接触的底层硬件;哇,并发好简单,好高效;哇,她不用任何框架中间件就能把web和数据打理的井井有条。她的缺点就是年纪小,成熟可用的库不多,但这正可以让我更多的DIY。我们相伴至今一年多,我又一次觉得我找到了真爱。rust嘛,发育太慢至今未成年,追求成本太高,风险不可控呀。 学Erlang吧…(逃)

首先你得先问自己,既然已经会了大蟒蛇,为什么还要再去学其他得编程语言?

至于我,答案是为了拓展自己的编程思维。

出于这个目的,我推荐rust。它强迫我审视代码的每一处,包括但不限于,变量的作用范围,最小化需要使用的api依赖。

这些是我在理解borrowing,ownership时*要去想清楚的。当然rust还有其他很多东西。

我学到的只是皮毛。

这里只是想强调它带给我思维上的变化。


很多人都说这门语言给人感觉很复杂。

其实没有,只是不习惯rust的编程方式罢了

对于Rust不熟悉,最近正在学习Go,个人感觉在syntax对于Pythonista有天然的亲和性
1.不用打分号
2.核心数据结构近似,slice对应list,map对于dict,操作符的风格几乎都是一样的
3.Go虽说的静态语言,但是由于有自动类型推导(:=)的存在,写起来不费事儿
4.duck typing

当然以上是从syntax角度来谈的,本质上Python和Go还是相当不同的语言,比如对待OOP的态度上面,两者相差就非常远。异常处理的风格也差别挺多的(不过这貌似是Go摒弃了一般意义上的基于继承的类型树的必然结果?)。Go在语言层面就自带一些concurrent feature对于Pythonista可能会比较新奇,比如channel/select等等。不过总的来说,有Python背景,Go的学习曲线会比较平稳。

延伸阅读:
s3.amazonaws.com/golang 题主自身的情况是:Python初学者,不理解指针概念,想再学一门快速编译型的语言,并要求在Go和Rust两者之间选择一个。

我只能帮题主推荐Go语言。你要简单,要编译快,并且二选一,那只能是Go语言。Rust语言相对而言要更复杂,更底层,不深刻理解指针概念显然是不可能学会Rust的。

但是,我个人不喜欢Go语言,还曾经写过一大篇《我为什么放弃Go语言》。跟另一位答主 @钟宇腾 一样,我选择Rust语言,我选择我喜欢。对于在C/C++领域摸爬滚打十多年的人群而言,Rust实在是太有诱惑力了。(初学者往往体会不到这一层。)