Rust `String` type/`read_line` 函数如何在没有被明确告知的情况下知道需要多少内存?
How does the Rust `String` type/`read_line` function know how much memory is needed without explicitly being told?
在 C 中,在使用 scanf
或 gets
"stdio.h" 函数获取和存储用户输入之前,程序员必须手动为读取的数据分配内存在 Rust 中,似乎可以使用 std::io::Stdin.read_line
函数,而无需程序员事先手动分配内存。它所需要的只是有一个可变的 String
变量来存储它读入的数据。它是如何做到这一点的,似乎不知道需要多少内存?
好吧,如果你想要详细的解释,你可以深入研究一下 read_line
method which is part of the 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_line
的 String
预先分配一点内存,可以使用 String::with_capacity
创建它。如果它不够大,这不会阻止 String
重新分配。
在 C 中,在使用 scanf
或 gets
"stdio.h" 函数获取和存储用户输入之前,程序员必须手动为读取的数据分配内存在 Rust 中,似乎可以使用 std::io::Stdin.read_line
函数,而无需程序员事先手动分配内存。它所需要的只是有一个可变的 String
变量来存储它读入的数据。它是如何做到这一点的,似乎不知道需要多少内存?
好吧,如果你想要详细的解释,你可以深入研究一下 read_line
method which is part of the 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_line
的 String
预先分配一点内存,可以使用 String::with_capacity
创建它。如果它不够大,这不会阻止 String
重新分配。