如何访问特征的默认方法定义中的结构字段?

How do I access struct fields within default method definitions of traits?

我看到了一些相关的问题(比如 and ),但我希望我的默认方法用例足够独特,可以问一个稍微不同的问题。以下最小示例有效并输出 "Sheriff Ted" shot "Billy the Kid"!:

#[derive(Debug)]
struct Actor {
    name: String,
}

fn main() {
    let cop = Actor {
        name: String::from("Sheriff Ted"),
    };

    let robber = Actor {
        name: String::from("Billy the Kid")
    };

    println!("{:?} shot {:?}!", cop.name, robber.name); // without the trait. with:
    // cop.shoot(&robber);
}

//pub trait Shoot {
//    fn shoot(&self, other: &Actor) {
//        println!("\n{:?} shot {:?}!",
//                 &self.name,
//                 &other.name,
//        )
//    }
//}
//
//impl Shoot for Actor {}

如您所见,我想将 Shoot 实现及其包含的 shoot 方法传递给 Actor 结构。当我取消注释 Shoot 特性、它在 Actor 上的实现以及调用 cop.shoot(&robber) 时,我也收到了与问题相关的错误消息:error[E0609]: no field 'name' on type '&Self'

我的第一个想法是在默认方法的签名中指定 &self: Actor,但这会产生定界符错误,因此在语法上是无效的。

我认为这个问题很独特,因为其他问题似乎误解了它们指定的泛型如何影响它们的预期类型,在我的例子中,我不明白为什么我不能访问结构中的字段我正在尝试实现默认方法。

这适用于只有 Actor 需要 shoot 的情况,但我正在寻找一种方法来跨多个应用此行为(现在,只是 printlning)类型。

impl Actor {
    fn shoot(&self, other: &Actor) {
        println!("\n{:?} shot {:?}!",
                 self.name,
                 other.name,
        )
    }
}

您没有尝试在任何结构上实现默认方法;您正在为该特征实施它。因此,您无法访问任何结构上的任何字段;您只能访问特征要求的内容。

特征方法的默认实现意味着任何实现特征非默认方法的类型都可以使用默认方法,无论它看起来像什么。但是您期望实现类型除了特征要求的内容之外还有一个 name 字段(顺便说一句,它不需要任何内容​​)。

这根本不是一个有效的假设。

我想知道你为什么要在这里使用特征。如果您同意在 shoot 方法中要求 selfActor,为什么它是特征方法?为什么它不是没有任何特征的 Actor 结构的固有方法?

在阅读了 Sebastian 的回复后,我认为 "answer" 是:你不能在 traits 的默认方法中命名结构字段,因为在实现之前你不知道结构可能有哪些字段特征。因此,您将定义一个(抽象的?)方法签名,然后在实现时将其具体化。就我而言,这有效:

trait Shoot {
    fn shoot(&self, other: &Actor);
}

impl Shoot for Actor {
    fn shoot(&self, other: &Actor) {
        println!("\n{:?} shot {:?}!",
            self.name,
            other.name,
        );
    }
}

仍然有兴趣知道我是否可以将特征限制为仅应用于具有特定字段的结构,以及这是否与 "trait bounds" 不同。 (我认为是...)