大家好,欢迎阅读我的“学习生锈”系列文章的第三篇。如果您想从一开始就点击它,这里有一个指向第一个的链接!这整个系列涵盖了我的旅程,从一个完全封闭在陆地上的地鼠,变成(希望如此)一只老练的Rustacean,能够安全地掠过任何应用程序的危险海床。
警告:即将到来的观点独白;如果你想要的是复习功课,请随时跳到复习复习。
让我开始不要在我还不太了解的概念上松散地思考,因为有足够的时间来做这件事,而是允许我画出我看到的铁锈和Go的风景。在相当发自内心的时候,我意识到这些现代语言的构建不仅是为了让我们的编程生活更愉快,而且是为了引导我们实现特定的工程和组织目标。
对新的通用语言的需求不再源于“简单的”软件问题。以使用变量(Assembly)、使用自定义数据类型(C)、跨平台、跨架构兼容性(JVM语言)甚至是非常简单(Python)的问题为例。今天的语言可以从前面的所有功能中选择功能,然后应用工程和组织方向。
自2014年以来,我一直把围棋作为一种爱好写东西,但直到2018年才开始专业写作。作为一个业余爱好者,我承认我曾经认为“围棋是固执己见的”。这看起来很酷,因为意见是有意义的!对吗?但是为什么它会固执己见,为什么呢?醒醒,伙计!
今天我对它有了完全不同的看法。围棋只是一种在工程师之间共享非常安全的语言。这是因为工程师在使用围棋时不需要做很多决定。如果一个应用程序在理论上已经完成了它的设计,那么实际上它通常只是一个敲打代码来使其成为现实的问题。
看看谷歌拥有多少Go开发工具就知道了。使用Java时,我记得在构建工具中选择Ant或Maven。围棋不让你选择。我们最接近的选择是依赖关系管理的dep。但最终谷歌屈服了,gomod成为了标准。围棋会尽最大努力剥夺你的选择。您不需要在Tomcat或Jetty之间进行选择-Go Net/http包将为您处理10kRPS,没有问题。见鬼,我看过服务于50kRPS的应用程序,而仅使用fmt.Println就记录了三分之一的请求。您只需远离标准库即可扩展,这是该语言的一个巨大优势。(这在很大程度上也是因为在过去的10年里,网络服务器并没有改变太多,所以围棋不必“跟上”--另一方面,我在围棋中使用http2的体验远非理想)。
这是到目前为止在公司使用Go的最大卖点。如果你需要雇佣帮手,你基本上可以找到任何有后台经验的人,他们会在一到两周内拿到90%的围棋。如果他们有使用Struts、JUnit或Spring的经验,您完全不需要担心-标准库中的内容已经很多了。我是认真的。他们需要知道如何传递指针或值吗?并非如此-一般的软件工程实践,如同行评审和简单的单元测试,可以很容易地发现这些类型的问题。
另一方面,现在谁还会雇佣我加入他们的铁锈团队呢?没有人-因为我会是那支球队的巨大负担。
Go的目的是让开发人员开发出可伸缩、易于开发且不需要关键任务性能的Web服务。
我是个菜鸟。100%。但即便如此,在我虚弱的脑海里,我已经明白了什么是铁锈。我看到了一把非常锋利的刀,但这把刀完全地、完全地被包裹在防篡改、防儿童、防盗、硬化和密封的塑料外壳中。是的,shell,就像shell的复数形式一样。这些外壳甚至也是成人专用的,成人是一名普通工程师,一般只接受过其他语言的培训。编译器就是包装,当它确切地知道您的行动计划时,它会让您挥舞这把刀。-但是,哦,不,不是任何计划都可以,你的计划必须遵守1938年《刀具安全测量法》及其相关修正案中的每一项规则和规定!!(这可能不是严格意义上的,因为我听说过一个不安全的关键字)。
但是为什么会有这么多塑料布洛赛登呢?你知道,我知道这是为了防止像我这样心地温和的人,不被那把非常锋利的刀划伤手指。回到元级别,这些手指甚至不一定属于我这个程序员,而是属于代码的最终用户。对于任何对Rust感兴趣的人来说,这都不是什么秘密,这种语言的一个主要驱动因素是能够用同样高效但不太容易受到安全漏洞攻击的东西来替换C++代码。因此,安全塑料的目的不是保护个人编码员,而是保护编码组织。
好了,你可能已经听够了我的观点,在这个比喻崩溃并真正伤害到某人之前,让我们继续前进吧。
本课中最先让人大吃一惊的时刻之一是这条编译器消息:
很自然地,我运行了列出的命令,这会将我带到一个较少的窗口(Buffer?)。包含以下内容:
重新指定了不可变变量。错误代码示例:';';';';';';';';';';默认情况下,Rust中的变量是不可变的。要修复此错误,请在声明变量时在关键字`let`后添加关键字`mu`。例如:';';';fn main(){设mut x=3;x=5;}';';';
这让我有点失望(&;mldrand)。这个“解释”里没有太多的信息。我继续让rustc向我“解释”更多的随机错误代码,其中大多数似乎也相当小或已被弃用。我希望要么是A)我不需要经常使用这个功能,要么B)我可以创建rustc/Cargo/IntelliJ,默认情况下只需告诉我详细信息即可。
由于某种原因,当我第一次看到它时,这让我很恼火(这条评论是从我的课堂笔记中逐字摘录的)。仔细一看,它似乎真的对可读性真的很有帮助。
这看起来是个很方便的把戏。您可以编写代码,就好像您的变量是不可变的一样,但是编译器会为您进行切换。然而,真正让我头晕目眩的是,你在了解所有权之前就已经了解了影子。那么,在这之后,我对影子的天真理解是否改变了呢?我不这么认为&至少我不这么认为。这是我写的一些东西来验证我的学习:
Fn main(){let mut s=string::from(";hello";);let r1=&;mut s;let r1=&;mut s;println!(";{}";,r1);}。
&;mldrand它起作用了。它还回答了我最初学习所有权时的一个问题。由于某种原因,当我读到书中的例子时,我想Rust可以推断出不可变引用的结束时间,但不能推断出可变引用的结束时间。我对此感到困惑,并有一个后续项目,但这个小例子证明我错了。快乐的日子!
无效的数组元素访问示例不起作用-它本应产生运行时错误,但却无法编译:
编译变量V0。1.0(/home/levi/rustprojs/Variables)错误:此操作将在运行时死机-->;src/main。RS:5:19|5|设element=a[index];|^index出界:镜头为5,索引为10|=备注:`#[DENY(无条件_PARGIC)]`默认开启。
我甚至不知道我是应该称这为“Nit”,还是应该直截了当地说“印象深刻”。铁锈是不是进化到了这本书再也不能欺骗我制造运行时恐慌的地步了?!我向上帝发誓,这是个直夹克级别的包装。热烈的掌声。
在这节课中拿到了许多好的指针后,我想我已经把自己提升了几个档次。也许是白腰带、双黄尖端或类似的东西&mldr“我们去散散步吧”我心平气和地想。我先向左看,然后向右看,在一条扬起的眉毛的掩护下,我选择向铁锈的肚子走去。
我选择了一条简单的道路。我选择了一些对所有初学者来说都很具体的东西。我选择了Hello_World&;mldr的巅峰。
&;mldr和俯冲我做到了。当我的头撞到这个宏硬的铁柱后,我直接撞到了地上。我的眼睛却直接瞥见了索伦,从那以后,我一直是瞎子:
#[MACRO_EXPORT]#[STRATE(FEATURE=";RUST1";,SING=";1.0.0";)]#[ALLOW_INTERNAL_USTRATE(PRINT_INTERNAL,FORMAT_ARGS_NL)]MACRO_RULES!Println{()=>;($crate::print!(";\n";));($($arg:tt)*)=>;({$crate::IO::_print($crate::format_args_nl!($($arg)*);})}。
看在上帝的份上,这对我所有感官的辛辣攻击到底是什么?
我在这里要说实话。见鬼,我不可能在第二十课结束前理解这个宏图。我会吗?实际上我不太确定。我想还有希望吧?第10章、第14章和第19章看起来都将是强制性的。希望强化&&;mldr?
如果在表达式末尾添加分号,则会将其转换为语句,然后该语句将不返回值。当您接下来探索函数返回值和表达式时,请记住这一点。
这是一种他妈的思维-大约在阅读这篇文章的10分钟前,我对自己说,分号似乎是可选的,在生锈的情况下有点毫无意义。孩子们,我在树林外面很远的地方。
不过,后来的一个想法确实让我想知道:Rustaceans真的只是在其getter函数的末尾编写表达式,还是显式返回更常见?
在Rust中,惯用的注释样式以两个斜杠开始注释,注释一直持续到行尾。对于超过一行的注释,您需要在每行包含//,如下所示:
奇怪的是,/**/样式注释被明确支持-我在读完这篇文章后尝试了一下。但是,整个评论子课没有提到它们吗?我猜这与作者使用的惯用限定词有关。如果是这样的话那很好,我只想知道是谁定义了这些成语,更好的是,给我指给我看“生锈成语圣经”。在围棋中,我们有有效的围棋。
我想,现在我突然想到,这本书可能就是我正在胡思乱想的那本“圣经”。但即便如此,我仍然认为它应该提到/**/,以及为什么我们不应该使用它们&&和mldr。
当你是新手的时候,你会看到很多关于Rust的事情,那就是所有权检查,所以我很高兴终于有一章向我展示了一些非常新奇的东西。顺便说一句,如果你还和我在一起,那么恭喜你--你有牛蛙般的耐心。
现在我要开始这一章,先说我在弦上被耍了。
这本书真的让我相信“铁锈”中确实有两种弦,我个人认为这对“铁锈”来说是一个非常大胆的举动。只是在接下来的30分钟里,作者才仁慈地告诉我,只有一根绳子!“特殊的”字符串字面值实际上只是在不可变的字符串片引用上加了一些糖。归根结底,我觉得自己被这一点欺骗了,但我想,如果人们不熟悉切片和参考资料等,那么也许这种教学方法是有意义的。
最终,在一种反高潮的半身像中,这一章对我生锈的大脑来说实际上是相当平淡无奇的。(嘿;我一直生活在可怕的围棋双关语中,好吧!)。在这一章中,我只有两件事想要更多地了解。第一个是特点,哦,天哪,这些听起来很有趣--不过我会有耐心的。第二个来自于引言中的这个花絮:
对于字符串类型,为了支持可变的、可增长的文本片段,我们需要在堆上分配一定数量的内存(编译时未知)来保存内容。这意味着:
当我们处理完字符串时,我们需要一种将该内存返回给分配器的方法。
第一部分由我们完成:当我们调用String::From时,它的实现请求它所需的内存。这在编程语言中几乎是通用的。
&;mldr我只是希望这本书能告诉我更多信息,即字符串是进行libc malloc调用,还是只是做了一个新的切片,而搅拌器有自己的幕后内存层?我90%肯定这一点稍后需要变得更清楚,以便编写好的Rust代码,这与Go形成鲜明对比,在Go中,对堆和堆栈分配几乎没有控制权(因此,知道或依赖运行时分配器的工作方式不会有很好的回报,因为这也总是会发生变化)。
这绝对是我可以自己深入了解的东西,但为了这个博客系列和我每晚自己的时间,我在很大程度上将我的探索限制在这本书一分钟一字不变地教给我的内容上。还记得索伦用普林特恩对我的眼睛做了什么吗?
在这里结束一篇双篇章的帖子,我认为教训是扎实的。默认情况下,不可变变量的恐惧正在消退,因为我了解了一些处理它们的模式。退一步说,在这么早的阶段就有一种语言引入堆栈和堆的概念是很好的,大约一年前我重读了那本C语言书,我甚至不认为里面提到了这些概念!?事实上,我读的最后一本深入研究这些概念的编程书籍是奇妙的RISC-V汇编语言书籍。所以,是的,拉斯特显然是提前为年轻的克拉比准备了餐桌。
我真的,真的很期待从“铁锈”这本书中解开下一课,希望你和我一起享受这段旅程。像往常一样,我非常感谢评论中的任何指导和更正,直到下一次地鼠和Rustaceans,Nofo a(再见)!