【问题标题】:How does the Rust `String` type/`read_line` function know how much memory is needed without explicitly being told?Rust `String` 类型/`read_line` 函数如何在没有明确告知的情况下知道需要多少内存?
【发布时间】:2021-05-01 09:42:30
【问题描述】:

在 C 中,在使用 scanfgets "stdio.h" 函数获取和存储用户输入之前,程序员必须手动为读取的数据分配内存。在 Rust 中, std::io::Stdin.read_line 函数似乎可以在程序员不必事先手动分配内存的情况下使用。它所需要的只是有一个可变的String 变量来存储它读取的数据。它是如何在不知道需要多少内存的情况下做到这一点的?

【问题讨论】:

  • Strings 可以动态调整其内部缓冲区的大小。
  • @pretzelhammer 什么是内部缓冲区,String 如何知道将其调整大小?
  • @nicoty read_line 以固定大小开始,并根据需要调整String 的大小,直到用完整行。等效功能也可以是 implemented in C,它不是 Rust 独有的。
  • 我明白了。感谢所有链接和澄清,它们帮助我更好地理解了这个问题。

标签: memory input memory-management rust io


【解决方案1】:

好吧,如果您想要详细解释,您可以深入了解read_line 方法,它是BufRead 特征的一部分。大大简化,函数如下所示。

fn read_line(&mut self, target: &mut String)
    loop {
        // That method fills the internal buffer of the reader (here stdin)
        // and returns a slice reference to whatever part of the buffer was filled.
        // That buffer is actually what you need to allocate in advance in C.
        let available = self.fill_buf();

        match memchr(b'\n', available) {
            Some(i) => {
                // A '\n' was found, we can extend the string and return.
                target.push_str(&available[..=i]);
                return;
            }
            None => {
                // No '\n' found, we just have to extend the string.
                target.push_str(available);
            },
        }
    }
}

所以基本上,只要在stdin 中找不到\n 字符,该方法就会扩展字符串。

如果您想提前为传递给read_lineString 分配一点内存,您可以使用String::with_capacity 创建它。如果String 不够大,这不会阻止String 重新分配。

【讨论】:

    猜你喜欢
    • 2019-08-08
    • 1970-01-01
    • 2021-12-09
    • 1970-01-01
    • 2012-01-02
    • 1970-01-01
    • 2017-01-20
    • 2011-09-27
    • 1970-01-01
    相关资源
    最近更新 更多