作者| William Woodruff
译者| Arvin,编辑责任|包容的封面/p头图| CSDN从东方IC下载
展出品| csdn (标识: csdn新闻) )。
以下是译文:
五年前,我写了一篇文章,论述了当时“迄今为止”最喜欢的脚本语言Ruby的讨厌之处。 (https://博客. yossarian.net/2015/09/28 /光纤加热- I -硬件关闭- ruby
今天,我将对我现在最喜欢的编译型语言Rust做同样的事。
正如kkdmj写的关于Ruby的帖子一样,这些投诉都是个人观点,反映了我目前对这门语言的最佳理解。 就像写关于Ruby的文章一样,这也是出于对Rust的爱。
闲话少说,让我们开始主题吧。
字符串地狱
我在开发中抱怨Rust字符串有两大方向:
1 .不知道字符串类型的不同
2 .字符串类型之间的转换方法太多了
字符串类型太多
五种不同的方法可以接受字符串[1]、字符串视图或字符串格式的方法签名。
str用于表示所借的字符串
String用于表示自己的字符串
OsStr用于表示从操作系统借用的字符串
OsString用于表示操作系统中自己的字符串
AsRef用于方法签名,表示廉价的str引用
(我知道最后一个不是真正的字符串类型,但经常出现在惯用的字符串处理代码中。 )
作为Rust的初学者,这些类型的差异非常令人困惑,更难理解引用(为什么我不能直接编写str? 从哪里可以得到str? 中显示了当前的缩放比例。
字符串之间的转换方法太多
多个字符串类型和相关特性提供了多个转换功能。
如果不考虑从str到String的两个Vec或[u8]的格式转换或往返,则至少存在这几种类型的String:from、to_string、to_owned、into
从字符串到str:as_str,as_ref,引用目标=str,x[.]
适用于OsStr和CStr的类似(可能受损的)方法
这些变换大多在性能上是等效的,Rust社区似乎对哪个“正确”存在分歧。
最终,我们习惯于根据上下文使用不同的字符串。 例如,into (表示将a str转换为a,String转换为可以返回它,to_owned ) )表示以后拥有该字符串的所有权)。
标准库间隙
Rust标准库存中存在一些空白,这些空白困扰着用户空间编程的各个方面:
目前无法获取用户的主目录。 STD : env : home _ dir被明确标记为已过时,建议用户使用第三方库dirs。 (但是,这个库已经不维护了。 有关详细信息,请访问GitHub链接: https://blog.yossarian.net/2020/05/2020
没有标准的扩展方式。 STD : fs :3360 canonical ize支持.和.但不支持~。 这其实和上面的点重复了。
不能从系统shell中调用命令。 我知道system[3]命令有很多问题。 我也同意应该隔离以防止意外使用,而不是用于运行其他进程的默认接口。 但是,所有这些都没有改变这样的事实:该命令有时很有用,在标准库中的实现比最终开发人员直接使用sh-c更可靠。
没有进行glob操作的标准方法。 glob第三方库似乎是执行此操作的半官方方法。
这些只是公认的微小差距,所有这些都可以通过高质量的第三方库解决。 但是,这些都会在开发过程中增加摩擦。 考虑到Rust的无摩擦特性,摩擦值得特别关注。
属性(属性) )。
我喜欢基于特质的组合。 但是我不喜欢下面这样的东西。
有人说忘记使用uses TD : 3360 io 3360 3360读取或uses TD 3360 3360 io 3360 3360写入方法了,实际上是因为我调用的方法在作用域中被调用。 我知道Rust为什么要这样做。 否则会发出编译器警告,但特别是没有使用导入时,仍然会感到不可思议。
为了特质而实现特质的语法。 I
mpl<T> for Trait for T where T: OtherTrait 虽然不算太糟糕,但它读起来不像impl Trait for OtherTrait那么自然。有时Rust编译器rustc需要我在静态函数(non-self)特质函数中添加where Self: Sized。我仍然不明白为什么有时需要这样做,而有时则不需要。但我相信这是有正当理由的。
无需扩展的安全索引
给定一个固定数组x = [T; N]和类型为U(U的约束为U::MAX < N)的索引变量i,通过x[i] 索引始终是安全的。尽管如此,Rust编译器rustc希望程序员能够明确将i扩展到usize:
fn main {let lookup_table: [u8; 256] = [0_u8; 256];let index = 5_u8;println!("{}", lookup_table[index]);}失败结果:
error[E0277]: the type `[u8]` cannot be indexed by `u8`--> src/main.rs:4:20|4 | println!("{}", lookup_table[index]);| ^^^^^^^^^^^^^^^^^^^ slice indices are of type `usize` or ranges of `usize`|= help: the trait `std::slice::SliceIndex<[u8]>` is not implemented for `u8`= note: required because of the requirements on the impl of `std::ops::Index<u8>` for `[u8]`虽然这可以理解,但要求程序员要么在索引计划中的任何位置使用as usize(冗长,并掩盖了索引背后为 u8的意图),要么将索引本身变成usize(也掩盖了意图,并使算术运算变得更容易超出界限),还是有些强求。
最后一点:cargo install 有时不能成功
我不知道这是不是一个真正的错误,但是由于我被它坑了几次,所以我将它加了进去。
cargo install显然不知道如何发现带后缀的软件包版本。例如,如果我发布myfakepackage为version 0.0.1-alpha.0,cargo install则会报告如下错误:
$ cargo install myfakepackageerror: could not find `myfakepackage` in registry `https://github.com/rust-lang/crates.io-index`你必须明确传递—version参数:
$ cargo install myfakepackage --version 0.0.1-alpha.0总结
我还有其他一些想讨论的内容(对于不支持特质的核心类型的别名,程序包生态系统的样式有点像JS / -y),但是我认为这样做有可能对我非常满意的语言太过消极。
五年过去了,我仍然喜欢Ruby,并且对Rust感到乐观。
备注说明:
1.没包括CString和&CStr,因为它们主要用于FFI上下文,并且可以理解为是不同的。↩
2.我知道在POSIX平台上可靠地获取用户的主目录实际上非常困难。但这并没有改变标准库应该尝试的事实。↩
3.恰当的例子:CLI经常公开钩点和回调,这些钩点和回调能够使用shell语法编写很有用
作者:William Woodruff,研究和工程实践者,开源软件参与者,软件库Homebrew软件开发成员,kbsecret的首席维护者
原文:https://blog.yossarian.net/2020/05/20/Things-I-hate-about-rust
本文为 CSDN 翻译,转载请注明来源出处。
6月2日20:00,CSDN 创始人&董事长、极客帮创投创始合伙人wjdgb携手全球顶级开源基金会主席、董事,聚焦中国开源现状,直面开发者在开源技术、商业上的难题,你绝不可错过的开源巅峰对谈!立即免费围观:
☞重磅!阿里巴巴开源首个边缘计算云原生项目 OpenYurt
☞腾讯面试题: 百度搜索为什么那么快? | 原力计划
☞都无代码了,还要程序员吗?
☞附代码 | OpenCV实现银行卡号识别,字符识别算法你知多少?
☞因为一个跨域请求,我差点丢了饭碗
☞区块链的 Layer 2 扩容(Scaling)是否兑现了其承诺?