У меня проблемы с пониманием того, как ссылки передаются через функции.Кажется, что следующий сценарий компилируется должным образом:
trait Trait {}
struct ImplementsTrait {}
impl Trait for ImplementsTrait {}
fn foo(t: &mut Trait) {
// ... use the mutable reference
}
fn forward(t: &mut Trait) {
foo(t); // forward the type '&mut Trait' to foo
}
fn main() {
let mut t = ImplementsTrait{};
forward(&mut t); // need to pass as reference because Trait has no static size
}
Однако при использовании API для ящика capnp я получаю неожиданное поведение:
fn parse_capnp(read: &mut BufRead) {
let reader = serialize_packed::read_message(read, message::ReaderOptions::new());
Ok(())
}
fn main() {
// ... ///
let mut br = BufReader::new(f);
parse_capnp(&mut br);
Ok(())
}
error[E0277]: the trait bound `std::io::BufRead: std::marker::Sized` is not satisfied
--> src/main.rs:18:16
|
18 | let reader = serialize_packed::read_message(read, message::ReaderOptions::new());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `std::io::BufRead` does not have a constant size known at compile-time
Подпись read_message
:
pub fn read_message<R>(
read: &mut R,
options: ReaderOptions
) -> Result<Reader<OwnedSegments>>
where
R: BufRead,
Похоже, что read
передается по значению, когда это &mut BufRead
, а read_message
ожидает &mut BufRead
.Единственный способ заставить этот фрагмент для меня скомпилировать - это изменить его на:
fn parse_capnp(mut read: &mut BufRead) {
let reader = serialize_packed::read_message(&mut read, message::ReaderOptions::new());
Ok(())
}
Я полагаю, что упускаю что-то простое в типах здесь.Мне кажется, это передает &mut &mut BufRead
, который не является ожидаемым типом, но компилируется.
Может ли кто-то добавить ясность в типы read
и t
для двух примеров?
Я просмотрел следующие темы:
Для первого потока я бы сказал, что сравнение с указателями в стиле C неверно из-за правил разыменования, применяемых Rust.