Когда существующую переменную кладут в кортеж, владение ею передаётся кортежу. В некоторых случаях важен и порядок этих действий, и ваш пример как раз из таких. Ваш код не скомпилируется, поскольку кортеж забирает значение раньше повторного обращения к нему (вызов message.len() происходит уже после перемещения). Но если написать вот так:
let message = String::from("hello");
let pair = (message.len(), message);
то компиляция пройдёт, потому что message.len() выполняется до передачи владения кортежу.
Ещё советую прочитать главу о владении в книге Rust (https://doc.rust-lang.org/book/ch04-01-what-is-ownership.html), это должно прояснить ситуацию.
Переведено с английского·Показать оригиналPutting an existing variable into a tuple transfers that variable's ownership to the tuple. In addition, the order in which those things happen matters in some situations, and your example is one of them. Your example won't compile because the tuple takes the value before you access it again (the message.len() call happens after the move). However, write it this way instead:
let message = String::from("hello");
let pair = (message.len(), message);
and compilation succeeds, since message.len() runs before the tuple takes ownership.
I'd suggest going through the rustbook ownership chapter (https://doc.rust-lang.org/book/ch04-01-what-is-ownership.html) as well, which should help make this clearer.