Rust 如何访问traits的默认方法定义中的struct字段?

Rust 如何访问traits的默认方法定义中的struct字段?,rust,traits,Rust,Traits,我看到了一些相关的问题(如和),但我希望我的默认方法用例足够独特,可以提出一个稍微不同的问题。下面的最小示例工作并输出“治安官Ted”射杀了“比利小子”: 正如您所看到的,我想要传授shot实现和shot方法,它包含在Actor结构上。当我取消注释Shoot特征、它在Actor上的实现以及调用cop.Shoot(&robert)时,我得到了与问题相关的错误消息,以及:error[E0609]:type'&Self'上没有字段'name'。 我的第一个想法是在默认方法的签名中指定&self:Act

我看到了一些相关的问题(如和),但我希望我的默认方法用例足够独特,可以提出一个稍微不同的问题。下面的最小示例工作并输出
“治安官Ted”射杀了“比利小子”

正如您所看到的,我想要传授
shot
实现和
shot
方法,它包含在
Actor
结构上。当我取消注释
Shoot
特征、它在
Actor
上的实现以及调用
cop.Shoot(&robert)
时,我得到了与问题相关的错误消息,以及:
error[E0609]:type'&Self'上没有字段'name'。

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

我认为这个问题是独特的,因为其他问题似乎误解了它们指定的泛型是如何隐藏其预期类型的,在我的例子中,我不理解为什么我不能访问我试图实现默认方法的结构中的字段

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

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

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

trait方法的默认实现意味着实现trait的非默认方法的任何类型都可以使用默认方法,不管它看起来是什么样子。但是您希望实现类型除了trait所要求的之外还有一个
名称
字段(顺便说一句,它不需要任何东西)

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


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

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

trait方法的默认实现意味着实现trait的非默认方法的任何类型都可以使用默认方法,不管它看起来是什么样子。但是您希望实现类型除了trait所要求的之外还有一个
名称
字段(顺便说一句,它不需要任何东西)

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


我想知道你为什么在这里使用一种特质。如果你同意在
shot
方法中要求
self
成为
Actor
,为什么这是一种特质方法?为什么它不是没有任何trait的
Actor
struct的固有方法?

阅读了Sebastian的回答后,我认为“答案”是:在trait的默认方法中不能命名struct字段,因为在实现trait之前,你不知道struct可能有哪些字段。因此,您需要定义(抽象?)方法签名,然后在实现时使其具体化。就我而言,这是可行的:

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

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

仍然有兴趣知道我是否可以将一个特征限制为仅应用于具有特定字段的结构,以及这是否与“特征边界”不同。(我认为是…

在阅读了Sebastian的回答之后,我认为“答案”是:不能在trait的默认方法中命名struct字段,因为在实现trait之前,您不知道struct可能有哪些字段。因此,您需要定义(抽象?)方法签名,然后在实现时使其具体化。就我而言,这是可行的:

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

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

仍然有兴趣知道我是否可以将一个特征限制为仅应用于具有特定字段的结构,以及这是否与“特征边界”不同。(我想是的……

我简化了我的示例,使其最小化,但许多其他东西也可以。火炮、加农炮或舰船结构(所有结构都有一个名称字段)都可以在其上实现此特性……这有意义吗?如果不是,你是说我只会将trait的实现约束到有这个name字段的东西吗?(根据您的建议添加了一个小的编辑…)我删减了我的示例,使其最小化,但许多其他内容也可以。火炮、加农炮或舰船结构(所有结构都有一个名称字段)都可以在其上实现此特性……这有意义吗?如果不是,你是说我只会将trait的实现约束到有这个name字段的东西吗?(根据您的建议添加了一个小的编辑…)您可以添加一个trait
NamedShooter
,它定义了一个getter方法
fn name(&self)->&str
。然后,您可以为
NamedShooter
实现添加
Shoot
的总体实现。您可以添加trait
NamedShooter
,它定义了getter方法
fn name(&self)->&str
。然后,您可以为
NamedShooter
实现添加一个
Shoot
的总体实现。我相信您的问题已经由的答案回答了。如果你不同意,请用你的问题来解释不同之处。否则,我们可以将此问题标记为已回答。@Shepmaster我在问题顶部引用的答案中没有一个明确说明(无论如何,对我来说)无法从默认方法定义访问结构字段,因为错误地假设结构将具有该字段(仍在探索如何使用绑定来确保使用前面提到的字段的结构类型)