use std::pin::Pin;
fn print_type_of<T>(_: &T) {
println!("{}", std::any::type_name::<T>())
}
fn test(s: String) {}
fn test2(s: Pin<&mut String>) {}
fn main() {
let s = String::from("abc");
print_type_of(&s);
tokio::pin!(s);
print_type_of(&s);
// test(s); error!
test2(s);
}
问题不在于为什么Pin
是什么或者为什么需要Pin
。
调用tokio::pin!
后,s
的类型从alloc::string::String
变为core::pin::Pin<&mut alloc::string::String>
。怎么会这样?在宏中改变外部变量的类型让我感到惊讶。
1条答案
按热度按时间ar7v8xwq1#
宏比函数更强大。它们在编译时被评估,并转换为代码 * 在同一范围内 * 它们被调用。尽管如此,宏can't access variables in that scope with hardcoded names, but it can if the identifier is received as a parameter.
还请注意,Rust允许隐藏(重新声明)同名变量。
例如:
工作正常。这两个
x
'es实际上并不是同一个变量,它们只是具有相同的标识符(“name”),而后者使前者不可访问。而宏 * 可以 * 发出隐藏变量的行。所以:
就像你写的一样
x
directly.至于为什么
tokio::pin
需要这样做,堆栈固定要求原始值永远不会再次移动。它可以通过隐藏变量来确保这一点,使其不再可访问。所以
pin
并不比这个多: