相关疑难解决方法(0)

有没有办法结合多个特征来定义新的特征?

有没有办法结合多个特征(通过继承?)来定义一个新的特征?我正在寻找像C++中的概念:

auto concept newConcept<typename T> : concept1<T>, concept2<T>, concept3<T> {};
Run Code Online (Sandbox Code Playgroud)

假设我想创建一个继承自的新特征Clone,Default以及其他一些特征,那可能吗?

rust

20
推荐指数
1
解决办法
6483
查看次数

Rust 中的“一揽子实现”是什么?

在查看 Rust 结构体的文档时,我经常会遇到标题为“Blanket Implements”的部分。我听说它可以用来实现所有类型或匹配某些条件的所有类型的特征,但我不确定为什么需要这样做。

那么一揽子实现到底是什么?为什么它们在 Rust 中有用?

rust

13
推荐指数
1
解决办法
4824
查看次数

具有相关类型的别名特征

是否可以使用指定的关联类型创建特征别名?我正在使用类似问题的方法为多个特征输入别名

trait Trait {
    type Item;
}

fn print<T>(value: T) where T: Trait<Item=char> {
}

trait Alias: Trait {}
impl<T: Trait<Item=char>> Alias for T {}

fn print_alias<T: Alias>(value: T) {
    print(value)
}

fn main() {
}
Run Code Online (Sandbox Code Playgroud)

但是无法编译并出现以下错误:

<anon>:12:5: 12:10 error: type mismatch resolving `<T as Trait>::Item == char`:
 expected associated type,
    found char [E0271]
<anon>:12     print(value)
              ^~~~~
<anon>:12:5: 12:10 note: required by `print`
<anon>:12     print(value)
              ^~~~~
error: aborting due to previous error
Run Code Online (Sandbox Code Playgroud)

围栏链接:http://is.gd/LE4h6a

rust

8
推荐指数
1
解决办法
1450
查看次数

如何为具有特征对象成员的结构实现调试特征?

我的目标是打印具有特征对象成员的结构的内容,但我找不到如何告诉 Rust 编译器该成员还实现了其他特征,例如Displayor Debug

例如,在下面的程序中,我想打印 的结构S2(并S1进行比较),但我陷入了 的实现中fmt

trait Tr {}

impl Tr for usize {}

impl Tr for String {}

#[derive(Debug)]
struct S1<A: Tr + std::fmt::Debug> {
    member: Box<A>,
}

struct S2 {
    member: Box<Tr>,
}

impl std::fmt::Debug for S2 {
    fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
        // ??
        Ok(())
    }
}

fn main() {
    let s1 = S1 {
        member: Box::new(String::from("abc")),
    };

    println!("{:?}", s1);

    let s2 = …
Run Code Online (Sandbox Code Playgroud)

traits rust

8
推荐指数
1
解决办法
7150
查看次数

用于定义特征别名的宏

根据这个问题和这个回答的问题,不可能简单地定义一个特征别名,如:

trait Alias = Foo + Bar;
Run Code Online (Sandbox Code Playgroud)

解决方法有点难看:

trait Alias : Foo + Bar {}
impl<T: Foo + Bar> Alias for T {}
Run Code Online (Sandbox Code Playgroud)

因此,我想为此定义一个宏.我试过了

macro_rules! trait_alias {
    ( $name : ident, $base : expr ) => {
        trait $name : $base {}
        impl<T: $base> $name for T {}
    };
}

trait Foo {}
trait Bar {}

trait_alias!(Alias, Foo + Bar);
Run Code Online (Sandbox Code Playgroud)

但它失败了,错误:

src\main.rs:5:17: 5:22 error: expected one of `?`, `where`, or `{`, found `Foo + Bar`
src\main.rs:5 …
Run Code Online (Sandbox Code Playgroud)

macros rust

6
推荐指数
1
解决办法
1003
查看次数

如何创建一个指定超级特征关联类型的特征?

我想创建一个抽象特征,它指定索引类型和值类型,其中实现该特征的任何结构都必须实现Index<IndexType>IndexMut<IndexType>定义Output在实现该特征的每个结构中保持相同的类型。

我尝试创建一个特征,但似乎无法指定输出类型:

use std::ops::{Index, IndexMut};

struct Coord;
struct LightValue;

trait LightMap: Index<Coord> + IndexMut<Coord> {}

impl LightMap {
    type Output = LightValue;
}
Run Code Online (Sandbox Code Playgroud)
warning: trait objects without an explicit `dyn` are deprecated
 --> src/lib.rs:8:6
  |
8 | impl LightMap {
  |      ^^^^^^^^ help: use `dyn`: `dyn LightMap`
  |
  = note: `#[warn(bare_trait_objects)]` on by default

error[E0191]: the value of the associated type `Output` (from the trait `std::ops::Index`) must be specified
 --> src/lib.rs:8:6
  |
8 | …
Run Code Online (Sandbox Code Playgroud)

rust

6
推荐指数
1
解决办法
951
查看次数

是否可以在特征中声明类型别名?

现有语法允许我们为关联类型编写默认值:

trait Foo {
    type Bar = i32;
}
Run Code Online (Sandbox Code Playgroud)

我想要类似 C++ 的东西:

trait Foo {
    typedef int Bar;
}
Run Code Online (Sandbox Code Playgroud)

这不是有效的 Rust 代码,但试图表明我的意图:

trait Foo<T> {
    trait Trait = Into<T> + /* 10 other traits dependent on T */;
    
    fn foo(x: Type) -> Trait;
}
Run Code Online (Sandbox Code Playgroud)

traits rust type-alias

6
推荐指数
1
解决办法
3224
查看次数

是否可以使用功能标志进行条件特征继承(例如发送+同步)?

在库中,人们可能希望根据功能标志将特征的实现限制为线程安全。这有时涉及改变特质继承。但是,特征继承边界上不允许使用属性。常见的解决方法是复制特征:

#[cfg(not(feature = "thread_safe"))]
pub trait MyTrait {
    fn foo();
}

#[cfg(feature = "thread_safe")]
pub trait MyTrait: Send + Sync {
    fn foo();
}
Run Code Online (Sandbox Code Playgroud)

可以通过使用宏来减少重复的代码(见下文),但这可能会影响 IDE 体验。有没有更好的方法来实现条件性状遗传?

macro_rules! my_trait {
    ($($bounds:ident),*) => {
        pub trait MyTrait where $(Self: $bounds),* {
            fn foo();
        }
    };
}

#[cfg(not(feature = "thread_safe"))]
my_trait!();
#[cfg(feature = "thread_safe")]
my_trait!(Send, Sync);
Run Code Online (Sandbox Code Playgroud)

rust

5
推荐指数
1
解决办法
270
查看次数

为 Fn 特征创建别名会导致“一种类型比另一种类型更通用”错误

我学到了一个习语,为 Trait 起一个别名。但是,当我将这个习惯用法应用到我的代码中时,我遇到了一个令人费解的错误。

这是代码的简化版本:

// `StrToStr` is an alias for `Fn(&str) -> &str`
trait StrToStr: Fn(&str) -> &str {}
impl<T> StrToStr for T where T: Fn(&str) -> &str {}

// A function that returns `StrToStr`
fn identity() -> impl StrToStr {
    |s: &str| s
}
Run Code Online (Sandbox Code Playgroud)

当我编译此代码时,出现以下错误:

error[E0308]: mismatched types
  --> src/main.rs:77:18
   |
77 | fn identity() -> impl StrToStr {
   |                  ^^^^^^^^^^^^^ one type is more general than the other
   |
   = note: expected reference `&str`
              found reference …
Run Code Online (Sandbox Code Playgroud)

rust

5
推荐指数
1
解决办法
527
查看次数

动态A+B可能吗?

AsyncWrite我有一个实现和 的自定义套接字AsyncRead。我想将 dyn 存储到该套接字,但我想同时使用两者AsyncWrite/Read,如下所示:

#[derive(Clone)]
pub struct AsyncTransporter {
    stream: Arc<dyn AsyncRead + AsyncWrite>,
}  
Run Code Online (Sandbox Code Playgroud)

但这不受支持。

60 |     stream: Arc<dyn AsyncRead + AsyncWrite>,
   |                     ---------   ^^^^^^^^^^ additional non-auto trait
   |                     |
   |                     first non-auto trait
   |
   = help: consider creating a new trait with all of these as super-traits and using that trait here instead: `trait NewTrait: tokio::io::AsyncRead + tokio::io::AsyncWrite {}`
Run Code Online (Sandbox Code Playgroud)

如果我这样做trait NewTrait: tokio::io::AsyncRead + tokio::io::AsyncWrite {},这两个特征的方法将如何实现?

rust

4
推荐指数
1
解决办法
385
查看次数

标签 统计

rust ×10

traits ×2

macros ×1

type-alias ×1