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