Macros 是否可以编写一个Rust宏;有你的特点!(<;type>;,<;ident>;|<;expr>;)";?

Macros 是否可以编写一个Rust宏;有你的特点!(<;type>;,<;ident>;|<;expr>;)";?,macros,rust,Macros,Rust,我想匹配,例如,一个ident的类型来实现某个特征,我该怎么做 以下是(不完整)代码中的基本思想: 我不知道该怎么说“任何一种具有traitFoo”的类型 我看到了两种解决问题的方法: 找到一个匹配表达式,该表达式匹配trait$t的任何类型,只需在匹配时返回true,否则(否则如何工作?)返回false 在任何类型的匹配体中,使用一些代码来确定trait$t是否由$x类型实现 我看不出两种选择中的任何一种都能做到 甚至可以这样做吗?您基本上想要的是静态(或编译时)反射: 根据系统类型,在编译时

我想匹配,例如,一个
ident
的类型来实现某个特征,我该怎么做

以下是(不完整)代码中的基本思想:

我不知道该怎么说“任何一种具有trait
Foo
”的类型

我看到了两种解决问题的方法:

  • 找到一个匹配表达式,该表达式匹配trait
    $t
    的任何类型,只需在匹配时返回true,否则(否则如何工作?)返回false
  • 在任何类型的匹配体中,使用一些代码来确定trait
    $t
    是否由
    $x
    类型实现
  • 我看不出两种选择中的任何一种都能做到


    甚至可以这样做吗?

    您基本上想要的是静态(或编译时)反射: 根据系统类型,在编译时分配值以在运行时使用。 这可能在例如D或C++中,而不是在锈蚀中。


    Rust不允许将模板专门化或编译时值作为通用参数,也不具有像D这样的静态反射功能。

    我担心这里存在一个关于宏可以做什么和不能做什么的严重误解

    在Rust中,宏作用于AST(抽象语法树的缩写)。这意味着它可以(仅)访问语法信息

    这意味着宏所做的任何事情,你也可以不用宏来做。宏只是一种语法糖,可以避免反复编写样板文件

    相反,如果没有宏就做不到,那么也不能用宏来做


    我现在还不清楚这些信息是否可用(证明负面信息总是很困难),但是可以肯定的是,宏的使用对可用性没有影响。

    正如其他答案已经说明的那样,宏无能为力。事实上,在当前(稳定的)锈蚀中,就是这样。然而,如果你愿意每晚使用,或者等到专业化稳定后再使用,你可以编写并实现一个特性来做出区分,例如

    #[feature(specialization)] // nightly only for now
    
    trait HasMyTrait {
        fn has_trait() -> bool;
    }
    
    impl<T> HasMyTrait for T {
        default fn has_trait() -> bool { false }
    }
    
    impl<T: MyTrait> HasMyTrait for T {
         fn has_trait() -> bool { true }
    }
    
    #[功能(专业化)]//目前只每晚
    特点我的特点{
    fn具有_trait()->bool;
    }
    impl HasMyTrait for T{
    默认fn具有_trait()->bool{false}
    }
    impl HasMyTrait for T{
    fn有_trait()->bool{true}
    }
    
    这只是一个简单的示例,但是如果所讨论的类型实现了或没有实现某个特性,则可以根据需要切换出任何功能的多个实现


    此代码要求从2016-06-02或更新版本起每晚运行Rust 1.11.0。

    我建议您通过询问问题来解释您的意图。如果你想要“任何具有trait
    Foo
    ”的类型,那只是普通的泛型类型,不需要宏:
    fn bar(val:T)
    。我想我会解释我试图做的事情:在宏中找到匹配表达式,匹配“任何具有trait Foo的类型”。我会添加一些重新表述问题的版本,由于某种神秘的原因,我无法编辑我自己的问题……现在还不清楚你为什么要这样做。如果您试图将一个没有实现trait的类型传递给一个需要它的函数,编译器会告诉您。有一个布尔值告诉你相同的信息有什么好处?至于“为什么”,这里有两种情况:1。我想编写宏为各种数据类型创建字符串,作为Rust宏系统的软预热练习。显然,IntoIterator类型将具有不同的表示形式(如整数值等)。2.假设您想向其他人指定他应该为您编写的类型应该支持的类型。在初始单元测试中,您可以编写“规范”,如
    has\u trait!(输入迭代器,Foo)
    然后让他去工作,让他知道你期望的是什么。这可能是你想检查的每个特征(或一组特征)所特有的,因此你可以使用宏来简化这9行代码的构造。当然,但在我的手机上键入这个版本已经够难了。;-)请注意,在我的评论中,专门化实际上是不可靠的,并且可以使用安全代码产生不安全的行为。我可能应该更新代码以使用基于autoref的专门化。它既可靠,也可在stable上使用。诸如:
    ty、ident、
    等已知的事实可能会导致这种误解。所以它已经知道令牌是一个类型、一个标识符,。。。但这可能就是它结束的地方。@BitTickler:啊,是的,Rust有一个规则的语法(希望是LL(1)),因为在这一点上,它只能是一个类型、标识符、表达式。。。但是请注意,
    ty
    可以互换地用于Type和Trait,并且您可以完美地为其使用不存在的类型,而不会产生任何问题(在这个阶段)。从语法的角度来看,类型是一种类型,即使它从未定义过。注意:Rust计划允许编译时值作为泛型参数(可能限制为整数)。编译时反射(按照序列化框架的要求)是通过插件执行的(只在夜间提供),而不是语言的正式部分;据我所知,没有计划将其进一步整合到语言中。
    #[feature(specialization)] // nightly only for now
    
    trait HasMyTrait {
        fn has_trait() -> bool;
    }
    
    impl<T> HasMyTrait for T {
        default fn has_trait() -> bool { false }
    }
    
    impl<T: MyTrait> HasMyTrait for T {
         fn has_trait() -> bool { true }
    }