首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在Rust宏中使用ty

如何在Rust宏中使用ty
EN

Stack Overflow用户
提问于 2016-05-05 19:31:27
回答 2查看 2.3K关注 0票数 4

我试图组成一个通用的解决方案,为单元测试锈蚀代码提供固定装置。我已经想出了一个宏,它允许用户定义安装和解压方法。到目前为止,我的解决方案如下:

代码语言:javascript
复制
struct FooTestFixture {
    pub name : String
}

impl FooTestFixture {
    fn setup() -> FooTestFixture {
        FooTestFixture { name: String::from("Initialised") }
    }
}

fn teardown(fixture : &mut FooTestFixture) {
    fixture.name = "".to_string();
}

macro_rules! unit_test {
    ($name:ident $fixt:ident $expr:expr) => (
        #[test]
        fn $name() {
            let mut $fixt : FooTestFixture = FooTestFixture::setup();
            $expr;

            teardown(&mut $fixt);
        }
    )
}

unit_test! (heap_foo_fixture_should_be_initialised_using_macro f {
    assert_eq!(f.name, "Initialised");
});

这个很管用。唯一的问题是,宏unit_test不是泛型的,并且绑定到夹具名称FooTestFixture。这意味着每个测试模块都需要为每个测试夹具重新定义这个宏,这并不理想。我想要做的是也引入一个类型变量,并在宏展开中使用该类型。深入研究宏,我发现有一个'ty‘项,它代表一个类型,我认为我可以这样做……

代码语言:javascript
复制
macro_rules! unit_test {
    ($name:ident $fixt:ident $ftype:ty $expr:expr) => (
        #[test]
        fn $name() {
            let mut $fixt : $ftype = $ftype::setup();
            $expr;

            teardown(&mut $fixt);
        }
    )
}

unit_test! (heap_foo_fixture_should_be_initialised_using_macro FooTestFixture f {
    assert_eq!(f.name, "Initialised");
});

但是,这不起作用,并导致以下错误:

src\tests\heap_fixture_with_new.rs:48:40: 48:50错误:$ftype:ty后面跟着$expr:expr,不允许ty片段src\tests\heap_fixture_with_new.rs:48 ($name:ident $fixt:ident $ftype:ty $expr:expr) => (

如您所见,在宏定义中,我已将对FooTestFixture的引用替换为$ftype。

我想达到的目标是可能的吗?这几乎就像我希望这个宏是泛型的,允许您传递一个类型,在宏定义中使用。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-05-05 19:51:36

我终于意识到我不需要ty了。我只需将类型指定为ident参数,这样就可以执行以下操作:

代码语言:javascript
复制
macro_rules! unit_test {
    ($name:ident $fixt:ident $ftype:ident $expr:expr) => (
        #[test]
        fn $name() {
            let mut $fixt = $ftype::setup();
            $expr;

            teardown(&mut $fixt);
        }
    )
}

unit_test! (foo_fixture_should_be_initialised_using_generic_macro f FooTestFixture {
    assert_eq!(f.name, "Initialised");
});
票数 3
EN

Stack Overflow用户

发布于 2016-05-05 19:51:44

ty不能直接跟在expr后面。一定是后面跟着一组特定的令牌

  • =>
  • ,
  • =
  • |
  • ;
  • :
  • >
  • [
  • {
  • as
  • where

exprstmtpathpat之后也存在类似的限制。这是在RFC 550引入到未来防锈语法的潜在变化中的。

要修复它,您需要改变宏的模式。

代码语言:javascript
复制
macro_rules! unit_test {
    ($name:ident $fixt:ident<$ftype:ty> $expr:expr) => (
//                          ^         ^ followed by '>' is OK

unit_test! (test_name fixture_name<FooTestFixture> f {    
//                                ^              ^
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37058836

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档