【问题标题】:How can I create a generic type that includes a trait如何创建包含特征的泛型类型
【发布时间】:2020-12-11 08:45:12
【问题描述】:

我发现我经常使用这种模式。

Arc<Mutex<dyn SomeTrait + Send>>;

所以我想我会这样做:

pub type NicePtr<T> = Arc<Mutex<dyn T + Send>>;

但这不会编译

   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

我认为这是可能的,但我只是不知道正确的语法。

【问题讨论】:

  • 类型参数目前不能被限制为特征(即使可以,类型别名中的通用边界目前也没有强制执行)。因此,使用类型别名是不可能的;您最好的选择是改用宏。 IMO 将声明保持原样以传达意图比将其隐藏在别名或宏后面更好。

标签: rust


【解决方案1】:

正如评论指出的那样,您可以使用宏完成与您想要的类似的事情。您可以拥有一个扩展为一种类型的宏和一个包装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());
}

将它与错误的类型一起使用甚至会给出有用的错误消息。

fn main() {
    // arrays don't implement Display!
    let example: nice_ptr!(dyn Display) = nice_ptr_new!([1,2,3]);
    println!("{}", example.lock().unwrap());
}
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)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-07-02
    • 2023-01-12
    • 2022-10-15
    • 2022-11-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多