我经常使用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
}
这是一种好的还是坏的做法?为什么?可能是什么缺点?
考虑以下实现:
pub struct BST {
    root: Link,
}
type Link = Option<Box<Node>>;
struct Node {
    left: Link,
    elem: i32,
    right: Link,
}
impl Link { /* misc */ }
impl BST { /* misc */ }
我一直收到错误:
不能定义
impl类型定义的包外的类型的固有内容; 改为定义和实现特征或新类型
有什么修复或其他方式让我Link在Rust中实现我的typedef?
这是枚举(除跳过顶部和底部4之外的所有值):
pub enum Spinners {
    Dots,
    Dots2,
    Dots3,
    Dots4,
    ...
    Shark,
    Dqpb,
    Weather,
    Christmas,
}
一个新的微调器很容易创建:
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();
}
但是,我希望随机选择一个微调器,这不起作用:
let spinner_enum = rng.choose(Spinners).unwrap_or(&Spinners::Dots9);
因为:
error[E0423]: expected value, found enum `Spinners`
let spinner_enum = rng.choose(Spinners).unwrap_or(&Spinners::Dots9);
                              ^^^^^^^^ not a value
如何随机选择枚举值,并使用它来显示随机微调器?
我刚刚遇到了为我不拥有的类型实现我不拥有的特征的问题。然后我用谷歌搜索了确切的如何为我不拥有的类型实现我不拥有的特征?问题。
让我困惑的是这种限制背后的动机。我来自 Scala,在那里可以为外部类型提供外部类型类实例。
为什么 Rust 会限制这一点?
因此,我认为出于向前兼容性考虑(以防止在库中添加进一步的 trait 实现破坏使用类型特征的地方),有理由禁止孤儿 trait 实现,并且可能使编译变得更加困难。但我想知道 Rust 社区认为哪种解决方法是最理想的:
(以防万一,这是不够的背景:我试图使用rusqlite与时辰的DateTime所以我想实现rusqlite的。FromSql和ToSql的性状DateTime<UTC>,但是这显然不是那么容易,因为我觉得这一定是-我刚开始目前使用 Rust。)
DateTime结构(可能是最好的解决方法,但我觉得这只是一些不必要的工作复制)。DateTime<UTC>特征并给它一个别名并为我的别名类型实现FromSql和ToSql特征(但是我认为这也不是微不足道的,当我尝试它时我无法让它工作,因为它仍然被视为外部类型)。我希望有人可以向我解释如何最好地解决这个问题,从我纯 OOP 经验来看,我只想能够继承DateTime和实现接口,但是(出于正当理由)这不是在 Rust 中完成的方式......
我有这个代码:
fn do_stuff() -> Result<i32, String> {
    let repo = git2::Repository::open(".")?;
    // ...
}
这不起作用,因为git2::Repository::open()的错误类型不是String。(是的,我使用字符串处理错误很懒惰。这是一个小程序;起诉我。)
fn do_stuff() -> Result<i32, String> {
    let repo = git2::Repository::open(".")?;
    // ...
}
我试过添加这个:
impl std::convert::From<git2::Error> for String {
    fn from(err: git2::Error) -> Self {
        err.to_string()
    }
}
但这是不允许的,因为它不引用此 crate 中定义的任何类型。
我知道我可能可以使用.map_err(),但我真的希望它自动发生。我有点觉得我以前也有这个工作,这有点烦人!
我想为一个原始类型提供一个特征的实现ToHex(我没有定义serialize)u8:
impl ToHex for u8 {
    fn to_hex(&self) -> String {
        self.to_str_radix(16)
    }
}
问题是我得到这个编译错误:
error: cannot provide an extension implementation where both trait and type are not defined in this crate
我理解这个错误的原因及其逻辑,这是因为特征和原始类型都在我的代码外部.但是我该如何处理这种情况并提供ToHex实现u8呢?更一般地说,你如何处理这类问题,在我看来,这个问题必须是常见的,它应该是可能的,并且很容易扩展这样的类型?
我是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)
    }
}
一个快速可运行的例子是
let t = Triangle { cur: 0, n: 0, m: 10 };
let s: u32 = t.sum();
println!("{}", s); …我有一个泛型类型,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,
        }
    }
}
但我得到这个错误:
type参数
T必须用作某些本地类型的类型参数(例如MyStruct<T>); 只有当前包中定义的特征可以为类型参数实现
使用您自己的类型作为右侧操作数重载运算符的标准方法是什么?
[编辑]
显然答案是你目前无法做到这一点."重复"中的相关问题有一些答案.我等待语言的更新,以便可以重新打开这个问题,并且可以给出实际的答案.
我正在尝试使用静态调度为板条箱 B 中的特性实现板条箱 A 的特性。我正在包装外来特征,但impl<T>在线路上遇到了问题:
extern crate a;
extern crate b;
pub trait C: a::A {}
impl<T: C> b::B for T {}
我正在寻找的最终结果是使用静态调度b::B为 trait 的实现者实现C。
我收到以下错误:
extern crate a;
extern crate b;
pub trait C: a::A {}
impl<T: C> b::B for T {}
我可以通过使用动态调度来解决这个问题impl b::B for dyn C——但想通过静态调度来实现这一点。
我已经试过了:
Vec,而是我自己的类型