在Read
trait中,许多函数/方法将buf: &mut XXX
作为(其中一个)参数并返回Result<usize>
。例如,read_to_string()
将buf: &mut String
作为参数之一,并返回Result<usize>
。
由于我来自多种语言,所谓的现代通常会返回read_string()
函数调用的字符串。 Rust中Read
特征的设计让我感到震惊,因为它不会返回字符串,而是将其作为参数传递(类似于C或其他更原始的语言)。
我知道返回值(Result
)用于指示读取是否成功,并且可以将其传递给match
表达式。 (我以前学过Lisp和Go,所以我不会质疑这种设计。)
为什么核心开发人员没有将此特征设计为“将字符串与错误消息一起返回”?
例如,为什么不这样设计:
fn read(&mut self) -> Result<String> { ... }
String
也包含长度,因此用户可以在需要时通过调用.len()
来访问长度。用户可以将其连接到他希望的任何其他String
,但关键是在调用此函数之前不需要创建/拥有一个。
有没有什么特别的理由来设计这个特性,就像它现在一样?
P.S。我还在学习Rust(关注The Rust Programming Language),并在阅读了大部分第一版后阅读第二版。如果上面的代码包含任何错误(特别是在处理生命周期时),请纠正我。
答案 0 :(得分:7)
我不知道真正的原因,但有一些优点:
String
的分配方式。您可以从池中取出它,重复使用它等。read_to_string
(或类似)调用中读取相同的字符串。没有必要连接字符串String
可能是非空的),这就是为什么{{1} }在usize
签名
Result
如果来自更高级别的语言,可能看起来更自然,但它无法控制fn read_to_string(&mut self) -> Result<String> { ... }
及其分配。
答案 1 :(得分:4)
RFC 517 (IO reform)州(强调我的):
read_to_end
和read_to_string
方法现在采用显式缓冲区 作为输入。这有很多好处:
性能。当知道阅读会涉及一些大的 字节数,缓冲区可以提前预先分配。
“原子性”问题。对于
read_to_end
,可以使用此API 保留到目前为止收集的数据,即使读取在中间失败。 对于read_to_string
,情况并非如此,因为UTF-8的有效性 在这种情况下无法保证;但如果中间结果是 想要,可以使用read_to_end
并仅转换为String
端。
在Rust 1.0之前,Reader::read_to_string
返回String
。这是一个故意决定摆脱这一点。
可以在read_and_create_string
的“顶部”创建Read::read_to_string
函数,但事实恰恰相反。标准库中的代码需要非常灵活。