“&*" 在 Rust 中有什么作用 [英] What does “&*” do in Rust

查看:86
本文介绍了“&*" 在 Rust 中有什么作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在从 Rust 库中阅读文档时遇到了这段代码:

I encountered this block of code while reading documentation from a Rust library:

for (ent, pos, vel) in (&*entities, &mut pos_storage, &vel_storage).join() {
    println!("Processing entity: {:?}", ent);
    *pos += *vel;
}

原文链接:https://slide-rs.github.io/specs/08_join.html

&*entities 在这里做什么.据我所知,它正在取消引用实体,然后再次引用它?

What does &*entities do here. From what I can tell it’s dereferencing entities and then referencing it again?

推荐答案

这是一个显式的重新借用,它是 Rust 中不时出现的常见习语.

This is an explicit reborrow and it's a common idiom that pops up in Rust from time to time.

  • & 在一个表达式中只有一个含义:它需要一个表达式(必须是一个 放置表达式) 类型T 并借用&T 类型的对它的引用.

  • & in an expression only has one meaning: it takes an expression (which must be a place expression) of type T and borrows a reference to it of type &T.

对于引用,*& 相反——它需要一个引用 (&T) 并使得T 类型的位置表达式.但是 * 可以用不同类型的指针表示不同的东西,因为你可以通过实现 Deref 来覆盖它.因为 * 与一些编译器魔术有关,自动取消引用 Deref::deref,您可以借用 * 的结果,通过使用 & 操作符将其转换回普通引用.

For references, * does the opposite of & -- it takes a reference (&T) and makes a place expression of type T. But * can mean different things with different kinds of pointers, since you can override it by implementing Deref. Because * ties in some compiler magic that automatically dereferences the return value of Deref::deref, you can borrow the result of *, turning it back into a plain reference, by using the & operator.

所以 &*foo 是一种显式地重新借用指向 T 的任何类型的指针"作为 &T 的方法,并且相当于手动调用Deref::deref(&foo).

So &*foo is a way of explicitly reborrowing "any kind of pointer to T" as a &T, and is the equivalent of manually calling Deref::deref(&foo).

(以上解释也适用于 &mut 借用 - 只需将 & 替换为 &mutDerefDerefMut.)

(The above explanation also works for &mut borrows -- just replace & with &mut and Deref with DerefMut.)

在示例中不清楚您链接什么 entities,但它可能是某种智能指针,其中 join() 方法需要一个简单的引用.对于另一个需要这样做的示例,请考虑使用 [&str]::concat 连接一个 String 和一些 &strs:

It's not clear in the example you link what entities is, but it's probably some kind of smart pointer, where the join() method requires a plain reference. For another example where this is required, consider using [&str]::concat to concatenate a String with some &strs:

// I want to concatenate this with some other strings
let s = String::from("Amelia");
// The following won't compile: you can't make an array of &str and String
assert_eq!(["Hello", ", ", s].concat(), "Hello, Amelia");    // WRONG
// However, &*s takes a reference to the str pointed to by s.
assert_eq!(["Hello", ", ", &*s].concat(), "Hello, Amelia");  // OK

另见

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆