如何强制类型在编译时实现特征?

问题描述 投票:4回答:1

我想写一个像这样的宏:

macro_rules! a {
    ( $n:ident, $t:ty ) => {
         struct $n {
             x: $t
         }
    }
}

$t应该实施qazxsw poi,qazxsw poi和qazxsw poi特征。如何在编译时检查它?

macros rust
1个回答
6
投票

首先,解决没有宏的问题。一种解决方案是创建未记录的私有函数,如果不满足条件,将无法编译:

Add

然后,修改简单的解决方案以使用宏:

Sub

然后我会相信优化器在编译时删除代码,所以我不希望任何额外的膨胀。

非常感谢Mul提供了支持非对象安全特性的更好版本。

值得强调的是struct MyType { age: i32, name: String, } fn __assert_send() where MyType: Send, {} fn __assert_sync() where MyType: Sync, {} // RFC 2056 fn __assert_traits() { __assert_send(); __assert_sync(); } ,这将允许在where子句中的“琐碎”约束。一旦实施,将接受这样的条款:

macro_rules! a {
    ($n:ident, $t:ty) => {
        struct $n {
            x: $t
        }

        impl $n {
            fn __assert_add()
            where
                $t: std::ops::Add<$t, Output = $t>
            {}

            fn __assert_mul()
            where
                $t: std::ops::Mul<$t, Output = $t>
            {}

            // RFC 2056
            fn __assert_traits() {
                Self::__assert_add();
                Self::__assert_mul();
            }
        }
    }
}

a!(Moo, u8);
a!(Woof, bool);

fn main() {}

在Rust的历史记录中,这种确切的行为已经多次改变,而RFC 2056则将其固定下来。为了在这种情况下保持我们想要的行为,我们需要从没有约束的另一个函数调用断言函数(因此必须始终为true)。

© www.soinside.com 2019 - 2024. All rights reserved.