Rust impl trait
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Rust impl trait相关的知识,希望对你有一定的参考价值。
参考技术Atrait特性可以理解为Java中的接口,具备和接口很类似的特性。trait中的函数叫做方法。某个结构体要么实现某个trait的全部方法,要么全部不实现。其中的impl trait特性也类似与java中返回一个接口对象。
在1.26版本后引入了存在类型(existential type的支持),这个特性就是通过impl trait实现,使得开发人员可以指定函数的返回类型,而不必具体指出是哪一种类型。
众所周知,通过Box装饰的变量保存在堆中,而Box的大小是固定的,只是通过一个指针指向堆中的变量,这样就不会违背运行时 必须知道返回值大小 的语法,例子如下。
impl trait只能返回相同类型的trait。比如对比上面的Box的动态分配,
只能都返回cat或都返回dog。这样就决定了返回值的大小是固定的。
Rust宏接受类型与通用参数
我有一个实现特征的宏,impl_Trait!()
。现在,它适用于没有泛型参数的类型,但我不确定如何将类型参数添加到impl
关键字。
macro_rules! impl_FooTrait {
($name:ty) => {
impl $crate::FooTrait for $name { ... }
};
}
struct Bar(i32);
impl_FooTrait!(Bar);
// All OK
struct Baz<'a>(&'a i32);
impl_FooTrait!(Baz<'a>);
// use of undeclared lifetime name `'a`
以免责声明的方式提交此答案:可能有更好的方法来做到这一点。我还不熟悉宏观的土地。
你可以使用tt
(单一标记)标识符来接受你想要的另一个宏臂(playground link)
macro_rules! impl_FooTrait {
($name:ty, $lifetime:tt) => {
impl<$lifetime> $crate::FooTrait for $name { }
};
($name:ty) => {
impl $crate::FooTrait for $name { }
};
}
struct Bar(i32);
impl_FooTrait!(Bar);
struct Baz<'a>(&'a i32);
impl_FooTrait!(Baz<'a>, 'a); // Use and declare the lifetime during macro invocation
看起来我觉得有点奇怪。我有兴趣看到任何其他有替代品的答案。
这是一个实际实现的例子:Playground link
这是一个老问题,但似乎在这里似乎没有一个好的答案。我有一个部分解决方案,虽然它匹配一些不正确的输入,我不能让它适用于生命周期参数。
#[macro_export]
macro_rules! impl_trait {
// this evil monstrosity matches <A, B: T, C: S+T>
// but because there is no "zero or one" rule, also <D: S: T>
($ty:ident < $( $N:ident $(: $b0:ident $(+$b:ident)* )* ),* >) =>
{
impl< $( $N $(: $b0 $(+$b)* )* ),* >
$crate::path::to::Trait
for $ty< $( $N ),* >
{
// function implementations go here
}
};
// match when no type parameters are present
($ty:ident) => {
impl_trait!($ty<>);
};
}
以上是关于Rust impl trait的主要内容,如果未能解决你的问题,请参考以下文章