我发现我经常使用这种模式。
Arc<Mutex<dyn SomeTrait + Send>>;
Run Code Online (Sandbox Code Playgroud)
所以我想我会这样做:
pub type NicePtr<T> = Arc<Mutex<dyn T + Send>>;
Run Code Online (Sandbox Code Playgroud)
但这不能编译
Compiling rsim v0.1.0 (C:\work\pdp\rsim)
error[E0404]: expected trait, found type parameter `T`
--> src\common.rs:9:37
|
9 | pub type NicePtr<T> = Arc<Mutex<dyn T + Send>>;
| ^ not a trait
Run Code Online (Sandbox Code Playgroud)
我认为这是可能的,但我只是不知道正确的语法。
正如评论指出的那样,您可以使用宏完成与您想要的类似的事情。您可以拥有一个扩展为一种类型的宏和一个包装宏Arc::new(Mutex::new())(或您认为合适的任何其他指针类型)。
use std::sync::{Arc, Mutex};
use std::fmt::Display;
macro_rules! nice_ptr {
// for types
($t:ty) => {
Arc<Mutex<$t>>
};
// for traits
($t:expr) => {
Arc<Mutex<$t>>
}
}
macro_rules! nice_ptr_new{
($inner:expr) => {
Arc::new(Mutex::new($inner))
}
}
fn main() {
let example: nice_ptr!(dyn Display) = nice_ptr_new!("example");
println!("{}", example.lock().unwrap());
}
Run Code Online (Sandbox Code Playgroud)
将其与错误的类型一起使用甚至会给出有用的错误消息。
fn main() {
// arrays don't implement Display!
let example: nice_ptr!(dyn Display) = nice_ptr_new!([1,2,3]);
println!("{}", example.lock().unwrap());
}
Run Code Online (Sandbox Code Playgroud)
15 | Arc::new(Mutex::new($inner))
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `[{integer}; 3]` cannot be formatted with the default formatter
...
20 | let example: nice_ptr!(dyn Display) = nice_ptr_new!([1,2,3]);
| ---------------------- in this macro invocation
|
= help: the trait `std::fmt::Display` is not implemented for `[{integer}; 3]`
= note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
= note: required for the cast to the object type `dyn std::fmt::Display`
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
Run Code Online (Sandbox Code Playgroud)