2020年的“学习锈”

2020-05-13 07:00:24

当我开始学习“锈”的时候,我犯了一个错误,那就是听从建议,先读这本书。虽然这是一个很棒的资源,但对于初学者来说,如果你想学习这门编程语言,被告知这是一种压倒性的感觉。如果你想学习这门编程语言,最好的入门方式就是阅读这本20章的书!大多数人在得到这样的建议之前就已经放弃了。从来没有人告诉别人读一本20章的书仅仅是为了开始使用Javascript或Python。拉斯特的学习曲线不是开玩笑的,但你必须给人们他们想要的,他们想要的是编程,而不是阅读编程。编程很有趣,而阅读编程就不那么有趣了。

这篇文章的前10%将是我给你的建议,告诉你如何在2020年学习Rust,遵循一种实用的动手编码方法。这是文章的精华部分。完成此部分后,您可以安全退出(我会告诉您何时退出)。这篇文章剩下的90%是我在抱怨大多数在线编码挑战网站对Rust的支持很差。

如果你是一个铁锈新手,想要在一天内学到尽可能多的东西,你应该阅读比莱姆更快的“学习铁锈的半小时”,然后查看令人敬畏的拉斯林斯回忆录并完成练习。

如果你是一个铁锈初学者,你应该开始练习锻炼的铁锈赛道。如果你被困住了,你应该向你的朋友Google和StackOverflow寻求帮助。我建议您花点时间轻松阅读和浏览Rust Standard Library Docs,它令人惊叹,并提供了简单的实用示例来说明如何使用其中的所有内容。Rust by Example也是一个非常好的高级参考,您可以用它来快速学习Rust语法和特性。如果你只想更深入地理解某个生锈的概念,那么我建议你在书中找到合适的章节来阅读。完成锻炼练习最好的部分是,你可以访问其他成员的所有解决方案,这些解决方案你可以根据最多的星号进行排序,从而看到特别惯用或聪明的解决方案。这是一个很好的学习方式!

在这一点上,你可能是一个高级初学者,可以找到自己的道路。如果您需要更多指导并希望继续开发小而简单的程序,我建议您做2018年代码来临日历中的练习。我特别推荐2018年日历的原因是,一旦你完成了一项练习,你就可以将你的解决方案与BurntSushi的2018年代码先锋生锈解决方案进行比较。BurntSushi编写了非常干净、易读、惯用的Rust代码。阅读一位经验丰富的Rustacean的代码将会教给你和练习本身一样多的东西。

另一个标题:Rust Beinnger可以用来练习编写小而简单的Rust程序的免费在线资源的评论。

这些资源中的大多数并不是专门为教授Rust而创建的,但是它们都可以用来学习和练习Rust,其中许多资源明确支持Rust提交,并提供特定于Rust的问题版本。

Rust是HackerRank支持的语言,除非您不允许提交其网站上大多数问题的Rust解决方案。我尝试直接上传我的解决方案,但他们拒绝了:

这真的很奇怪,因为我能够浏览由其他HackerRank用户提交的上述问题的Rust解决方案,因此以某种方式提交Rust解决方案是可能的。我试着用谷歌搜索这个问题,但是谷歌没有返回任何有用的结果。除了告诉你不要像我那样浪费时间在HackerRank上,我没有别的办法来评价HackerRank。

当我在2012年第一次开始学习编程时,我经常听说,如果你想快速掌握一门新的编程语言,用它解决一些Project Euler问题!";这在当时是不错的建议,因为没有太多其他的选择,但在我看来,Project Euler与编程几乎没有什么关系。项目Euler问题更多的是数学问题,而不是编程问题。他们的挑战几乎完全在于获得解决方案所需的数学推理,因为所需的编程通常是微不足道的。我不建议解决欧拉项目的问题作为学习锈蚀的一种方式,除非你是一个非常数学的收录,并有一些怀旧的网站。

Ruust是LeetCode上支持的语言。对于LeetCode上的每个问题,您都会得到一个解决方案模板,该模板通常包含单个未实现的函数,然后您必须实现并提交该函数才能解决问题。对于更复杂的问题,解决方案模板可能包括带有几个未实现方法的结构和Impl块。不幸的是,这些解决方案模板不是人工创建的,它们是自动生成的,这导致了大量非常笨拙和单一的锈蚀代码。例如:

选项<;Rc<;RefCell<;Node>;>;>;对于树链接和选项<;Box<;Node>;同样有效,并且更易于使用。

变异自身的方法需要可变地借用它,例如FN插入(&;mut self,val:I32)。

带符号的32位整数用于所有数字,即使问题未针对非负整数定义,例如fn nth_fib(n:i32)->;i32。

对于非负整数未定义的问题应使用无符号整数,例如fn nth_fib(n:u32)->;u32。

函数始终取得其参数的所有权,即使这是不必要的,例如FN SUM(Nums:VEC<;I32>;)->;I32

函数有时会忽略基本错误情况,例如对于FN get_max(Nums:VEC<;I32>;)->;I32如果Nums为空,应该返回什么I32?

如果结果可能是未定义的,则应将返回类型包装在选项中,例如fn get_max(number:&;[I32])->;option<;I32>;

LeetCode不允许您在解决方案中引入第三方依赖项。通常情况下,我认为这对于大多数语言都是可以的,但是Rust有一个非常小的标准库,它甚至不包括正则表达式支持,所以LeetCode上的许多更复杂的字符串解析问题在Rust中是毫无意义的难以解决的,但是在其他在其标准库中有正则表达式支持的语言中有一些微不足道的解决方案。

并发类别中的所有问题都不接受Rust中的解决方案。什么?无所畏惧的并发是Rust';的主要卖点之一!

解决问题后,您可以转到问题的评论部分查看其他用户的解决方案(因为许多用户喜欢在那里发布他们的解决方案),但是由于Rust在LeetCode上并不是很受欢迎,所以有时您不会找到任何Rust解决方案。

LeetCode有数量惊人的非常低质量的问题。用户可以喜欢问题,也可以不喜欢问题,但即使问题达到非常高的不喜好率,问题也永远不会被删除。我在100+投票和80%+不喜欢的比率上看到了很多问题,我不明白为什么要把它们放在网站上。

问题难度等级有点低。问题分为容易问题、中等问题或困难问题,但有许多容易问题的解决率低于许多困难问题。

并非所有问题都接受所有语言的解决方案,而且您无法根据问题接受的语言筛选问题。例如,LeetCode上的所有图形问题都不接受铁锈解决方案。

LeetCode在陡峭的月度付费墙后面屏蔽了高级问题,但不提供任何形式的高级免费试用,所以无法判断质量是否真的比免费问题更好。

问题的解决方案是针对一套秘密的单元测试进行测试的,但是如果您没有通过特定的测试用例,它们会向您显示失败的用例。

Codewar是一个容易误导的名字。Codewar没有发生战争。解决问题没有时间限制,您的解决方案不会根据执行速度或内存使用情况进行评判。你不是在与任何人竞争。这不是坏事,只是值得一提的是。

Ruust是Codewar支持的语言。对于CodeWare上的每个问题,您都会得到一个解决方案模板,该模板通常包含单个未实现的函数,然后您必须实现并提交该函数才能解决问题。这些解决方案模板是由人创建的,包括不熟悉铁锈的人,因此您偶尔会遇到一些笨拙和不自然的铁锈。例如:

对于没有为非负整数定义的问题,有时会采用带符号整数参数,例如fn nth_fib(n:I32)->;I32。

如果问题不是为非负整数定义的,则使用无符号整数参数,例如fn nth_fib(n:u32)->;u32。

有时问题会要求您为空值返回-1,例如FN GET_INDEX(针:I32,干草堆:&;[I32])->;I32。

如果结果可以为NULL,则应将返回类型包装在选项中,例如FN GET_INDEX(针:I32,干草堆:&;[I32])->;选项<;usize>;

以上所有问题只是偶尔会发生,因为在Codewar上有不同技能水平的Rustaceans将问题转换为铁锈。与LeetCode相比,这是一个巨大的进步,在LeetCode中,所有生成的锈蚀问题代码都是统一的。然而,作为一个整体,Codewar上的Rust社区可能倾向于缺乏经验的一方,因为我已经看到一些非常受欢迎的惯用解决方案,这些解决方案也有一点尴尬。例如:

有时在功能块的末尾使用显式返回,例如返回结果;

块作为表达式求值并隐式返回其最后一项,不需要在函数块末尾显式返回,例如RESULT。

我经常试图不惜一切代价,只使用迭代器来解决问题。

迭代器是富有表现力和习惯用法的,但是如果您必须在一行中链接15个迭代器,并且其间有多个级别的嵌套迭代器,那么您可能应该考虑重构以使用一些助手函数、中间变量,甚至可能是for循环。

再说一次,上述问题只是偶尔会发生。一个有经验的Rustacean可以很容易地发现它们,但这些网站上有很多铁锈新手,他们没有任何线索,他们正在学习反模式。

Rust在Codewar上似乎不那么受欢迎,该网站有9000个练习,但只有300个被翻译成了Rust;

您的解决方案针对一套秘密的单元测试进行测试,如果您没有通过其中一个秘密的单元测试,您就没有看到失败的测试用例。如果测试用例测试的是问题描述中没有清楚说明的边缘用例,这尤其令人恼火。

这里有一个第三方依赖项的小白名单,您可以使用它来帮助解决与Rust有关的问题。这份白名单包括:Rand、chrono、regex、serde、itertools和lazy_static,这有助于完善Rust的标准库,使其与其他语言更接近。

提交问题的解决方案也会自动发布该解决方案。您可以查看和提升其他成员的解决方案。您可以按最大升序对解决方案进行排序,以查看特别简明和聪明的解决方案,这有时也会非常惯用(但有时不是,如上所述)。

问题难度评分相当不错!Codewar不像LeetCode那样对问题进行简单、中等或困难的评分,而是选择从容易到困难的顺序对问题进行评分:8kyu、7kyu、6kyu、5kyu、4kyu、3kyu、2kyu、1kyu。我在8kyu-4kyu的范围内完成了60道题,每一关都比上一关更难一些,这符合我的预期。

“代码的出现”完全是语言不可知的。乍一看,这似乎是一个减号,但看看HackerRank、LeetCode和Codewar在他们的网站上对Rust的支持是多么可怕,这实际上是一个加号。代码的出现也被放在前面提到的网站之上,因为在我看来,AOC的练习真的很有趣,多样化,而且质量很高。

在你完成练习后,除非你在谷歌上搜索别人的锈蚀解决方案,否则你无法看到他们的解决方案,即使你在那里找到了一些,也不知道他们有多好或有多惯用。

要解决上述问题,我建议您浏览一下2018年日历问题,并将您的解决方案与BurntSushi的AOC 2018年生锈解决方案进行比较。BurntSushi编写了非常干净、易读、惯用的Rust代码。如果您想浏览2019年日历,我建议您将您的解决方案与bcmyers 2019年铁锈解决方案进行比较。我特别推荐bcmyers的原因是,他在YouTube上制作了一个他编码解决方案的播放列表,他很好地解释了他的思维过程,以及为什么他在编码时要做他正在做的事情。

语言不可知论,所以虽然它没有教你任何生锈模式,但它至少也没有教你任何生锈反模式。

沙沙声太棒了。所有的罗斯林斯练习都是用爱为铁锈手工制作的,这是一股美妙的新鲜空气。最后是一套真正教会你习语生锈的练习!

如果你是一个彻头彻尾的生锈新手,你绝对应该检查一下拉斯林斯,并开始练习。我强烈建议你先读“半小时学锈”这本书,因为它会让你超级快地掌握很多锈的语法和概念。(译注:我强烈建议你先读半个小时才能学到锈,因为它会让你超级快地掌握很多锈的语法和概念。)。

我只有一个小小的鲁斯特林斯批评:在错误处理和转换练习中有一些突如其来的难度峰值,我可以看到一些用户被这些练习搞得不知所措。我想很有可能挺过去,或者至少我希望。

我还有一个不能批评的小问题:它太短了。这不是批评,因为它是罗斯林斯的设计目标之一,是快速而温和地介绍铁锈,但它是如此之好,当然,我希望它能以某种方式更长。

锻炼有一个生锈的轨迹,这是一个大致按科目和难度排序的练习的集合。铁锈赛道与其他赛道有许多相同的练习,但所有的练习都是由经验丰富的Rustaceans翻译成铁锈的,不会出现任何在LeetCode和Codewar上常见的尴尬的统一生锈问题。大约有十几个特定于Rust的问题需要您实现一个标准库特征,或者编写一个宏,或者使用多个线程编写并行解决方案,或者编写不安全的Rust代码。到目前为止,这些练习是赛道上的亮点,我希望有更多的练习。作为一种学习“锈”的资源,锻炼是仅次于“锈”的。我把它放在罗斯林斯上面的唯一原因是,罗斯林斯可以在一个晚上完成,而Exercism的铁锈赛道至少需要一个月的时间才能完成,所以它的内容要多得多。

导师模式是没有用的,因为网站上的大多数铁锈导师都是不活跃的,而且学生人数远远超过他们,所以最好是在练习模式下进行一次培训。(这句话的意思是:“指导模式”是没有用的,因为网站上的大多数“铁锈导师”都是不活跃的,而学生人数又远远超过了他们),所以最好是在实践模式下进行一次培训。

共有92个练习,但其中很大一部分并没有真正教会你任何新东西,所以它们感觉有点像是忙碌的工作。他们可能会从赛道上删减大约20个练习,让赛道感觉更紧。

问题的难度等级比较高,容易的问题容易,中等的问题中等,难的问题难。

提交解决方案后,您可以浏览其他用户的解决方案,还可以根据获得最多星级的解决方案进行排序。