相关疑难解决方法(0)

为newtypes实现Deref被认为是一种不好的做法吗?

我经常使用newtype模式,但我厌倦了写作my_type.0.call_to_whatever(...).我很想实现这个Deref特性,因为它允许编写更简单的代码,因为我可以使用我的newtype,好像它在某些情况下是底层类型,例如:

use std::ops::Deref;

type Underlying = [i32; 256];
struct MyArray(Underlying);

impl Deref for MyArray {
    type Target = Underlying;

    fn deref(&self) -> &Self::Target {
        &self.0
    }
}

fn main() {
    let my_array = MyArray([0; 256]);

    println!("{}", my_array[0]); // I can use my_array just like a regular array
}
Run Code Online (Sandbox Code Playgroud)

这是一种好的还是坏的做法?为什么?可能是什么缺点?

dereference rust

24
推荐指数
2
解决办法
2542
查看次数

是否可以在类型别名上实现固有方法?

考虑以下实现:

pub struct BST {
    root: Link,
}

type Link = Option<Box<Node>>;

struct Node {
    left: Link,
    elem: i32,
    right: Link,
}

impl Link { /* misc */ }

impl BST { /* misc */ }
Run Code Online (Sandbox Code Playgroud)

我一直收到错误:

不能定义impl类型定义的包外的类型的固有内容; 改为定义和实现特征或新类型

在2月份找到了其他同样的问题,但当时看似没有解决方案.

有什么修复或其他方式让我Link在Rust中实现我的typedef?

rust

12
推荐指数
1
解决办法
4413
查看次数

如何从枚举中选择随机值?

纺纱箱有一个枚举有一个大的选择可能微调的.

这是枚举(除跳过顶部和底部4之外的所有值):

pub enum Spinners {
    Dots,
    Dots2,
    Dots3,
    Dots4,
    ...
    Shark,
    Dqpb,
    Weather,
    Christmas,
}
Run Code Online (Sandbox Code Playgroud)

一个新的微调器很容易创建:

extern crate spinners;

use spinners::{Spinner, Spinners};
use std::thread::sleep;
use std::time::Duration;

fn main() {
    let sp = Spinner::new(Spinners::Dots9, "Waiting for 3 seconds".into());
    sleep(Duration::from_secs(3));
    sp.stop();
}
Run Code Online (Sandbox Code Playgroud)

但是,我希望随机选择一个微调器,这不起作用:

let spinner_enum = rng.choose(Spinners).unwrap_or(&Spinners::Dots9);
Run Code Online (Sandbox Code Playgroud)

因为:

error[E0423]: expected value, found enum `Spinners`

let spinner_enum = rng.choose(Spinners).unwrap_or(&Spinners::Dots9);
                              ^^^^^^^^ not a value
Run Code Online (Sandbox Code Playgroud)

如何随机选择枚举值,并使用它来显示随机微调器?

enums rust

10
推荐指数
1
解决办法
2393
查看次数

为什么 Rust 阻止为外部结构实现外部特征?

我刚刚遇到了为我不拥有的类型实现我不拥有的特征的问题。然后我用谷歌搜索了确切的如何为我不拥有的类型实现我不拥有的特征?问题。

让我困惑的是这种限制背后的动机。我来自 Scala,在那里可以为外部类型提供外部类型类实例。

为什么 Rust 会限制这一点?

traits rust

9
推荐指数
1
解决办法
7001
查看次数

为外来类型实现外来特征

因此,我认为出于向前兼容性考虑(以防止在库中添加进一步的 trait 实现破坏使用类型特征的地方),有理由禁止孤儿 trait 实现,并且可能使编译变得更加困难。但我想知道 Rust 社区认为哪种解决方法是最理想的:

(以防万一,这是不够的背景:我试图使用rusqlite时辰DateTime所以我想实现rusqlite的。FromSqlToSql的性状DateTime<UTC>,但是这显然不是那么容易,因为我觉得这一定是-我刚开始目前使用 Rust。)

  • Fork rusqlite 并实现 trait。(我有点觉得这不是最好的方法,因为也许只有我需要在那里实现这个特征,所以我最终可能不得不让我自己的叉子保持最新状态。我也无法实现特性,因为有一些复杂的泛型我还不完全理解。
  • 实现我自己的DateTime结构(可能是最好的解决方法,但我觉得这只是一些不必要的工作复制)。
  • 不知何故“复制”DateTime<UTC>特征并给它一个别名并为我的别名类型实现FromSqlToSql特征(但是我认为这也不是微不足道的,当我尝试它时我无法让它工作,因为它仍然被视为外部类型)。

我希望有人可以向我解释如何最好地解决这个问题,从我纯 OOP 经验来看,我只想能够继承DateTime和实现接口,但是(出于正当理由)这不是在 Rust 中完成的方式......

rust

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

轻松将第三方错误转换为字符串

我有这个代码:

fn do_stuff() -> Result<i32, String> {

    let repo = git2::Repository::open(".")?;
    // ...
}
Run Code Online (Sandbox Code Playgroud)

这不起作用,因为git2::Repository::open()的错误类型不是String。(是的,我使用字符串处理错误很懒惰。这是一个小程序;起诉我。)

fn do_stuff() -> Result<i32, String> {

    let repo = git2::Repository::open(".")?;
    // ...
}
Run Code Online (Sandbox Code Playgroud)

我试过添加这个:

impl std::convert::From<git2::Error> for String {
    fn from(err: git2::Error) -> Self {
        err.to_string()
    }
}
Run Code Online (Sandbox Code Playgroud)

但这是不允许的,因为它不引用此 crate 中定义的任何类型。

我知道我可能可以使用.map_err(),但我真的希望它自动发生。我有点觉得我以前也有这个工作,这有点烦人!

rust

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

当特征和类型都不在此包中时提供实现

我想为一个原始类型提供一个特征的实现ToHex(我没有定义serialize)u8:

impl ToHex for u8 {
    fn to_hex(&self) -> String {
        self.to_str_radix(16)
    }
}
Run Code Online (Sandbox Code Playgroud)

问题是我得到这个编译错误:

error: cannot provide an extension implementation where both trait and type are not defined in this crate
Run Code Online (Sandbox Code Playgroud)

我理解这个错误的原因及其逻辑,这是因为特征和原始类型都在我的代码外部.但是我该如何处理这种情况并提供ToHex实现u8呢?更一般地说,你如何处理这类问题,在我看来,这个问题必须是常见的,它应该是可能的,并且很容易扩展这样的类型?

traits rust

7
推荐指数
2
解决办法
2727
查看次数

是否可以在Rust中实现自定义Iterator :: sum?

我是Rust的新手,我正在努力学习迭代器.我正在研究的具体问题是产生三角形数字的迭代器(三角形数字为1,3,6,10,15,其中1 = 1,3 = 1 + 2,6 = 1 + 2 + 3等).我有这个创建的基础知识,如下所示:

pub struct Triangle {
    cur: u32,
    n: u32,
    m: u32,
}

impl Iterator for Triangle {
    type Item = u32;

    fn next(&mut self) -> Option<u32> {
        if self.n == self.m {
            return None;
        }
        self.n = self.n + 1;
        self.cur = self.cur + self.n;

        Some(self.cur)
    }
}
Run Code Online (Sandbox Code Playgroud)

一个快速可运行的例子是

let t = Triangle { cur: 0, n: 0, m: 10 };
let s: u32 = t.sum();
println!("{}", s); …
Run Code Online (Sandbox Code Playgroud)

iterator rust

7
推荐指数
1
解决办法
684
查看次数

如何为一般的右手操作数重载操作符?

我有一个泛型类型,Vec2<T>我想为此实现以下操作:

Vec2<T> = T * Vec2<T>

我试过这个:

impl<T: Copy + Mul<Output = T>> Mul<Vec2<T>> for T {
    type Output = Vec2<T>;

    fn mul(self, rhs: Vec2<T>) -> Vec2<T> {
        Vec2 {
            x: self * rhs.x,
            y: self * rhs.y,
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

但我得到这个错误:

type参数T必须用作某些本地类型的类型参数(例如MyStruct<T>); 只有当前包中定义的特征可以为类型参数实现

使用您自己的类型作为右侧操作数重载运算符的标准方法是什么?

[编辑]

显然答案是你目前无法做到这一点."重复"中的相关问题有一些答案.我等待语言的更新,以便可以重新打开这个问题,并且可以给出实际的答案.

generics operator-overloading traits rust

7
推荐指数
0
解决办法
274
查看次数

为本地泛型类型实现外部特征

我正在尝试使用静态调度为板条箱 B 中的特性实现板条箱 A 的特性。我正在包装外来特征,但impl<T>在线路上遇到了问题:

extern crate a;
extern crate b;

pub trait C: a::A {}

impl<T: C> b::B for T {}
Run Code Online (Sandbox Code Playgroud)

我正在寻找的最终结果是使用静态调度b::B为 trait 的实现者实现C

我收到以下错误:

extern crate a;
extern crate b;

pub trait C: a::A {}

impl<T: C> b::B for T {}
Run Code Online (Sandbox Code Playgroud)

我可以通过使用动态调度来解决这个问题impl b::B for dyn C——但想通过静态调度来实现这一点。

我已经试过了:

rust

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