简体   繁体   English

如何使用特征默认方法中的BorrowMut超特征访问结构域?

[英]How do I use a BorrowMut supertrait to access struct fields in a trait default method?

Consider the following Rust code 考虑以下Rust代码

trait Trait {
    fn show_name(&self) {}
}

struct Foo {
    name: String,
    things_and_stuff: usize,
}

impl Trait for Foo {
    fn show_name(&self) {
        println!("{}", self.name);
    }
}

struct Bar {
    name: String,
    other_field: i32,
}

impl Trait for Bar {
    fn show_name(&self) {
        println!("{}", self.name);
    }
}

The two show_name functions have exactly the same code. 这两个show_name函数具有完全相同的代码。 It would be convenient if I could put that method as a default method on Trait , but that's not possible because traits cannot access struct fields. 如果可以将该方法作为Trait的默认方法,那将很方便,但这是不可能的,因为traits无法访问struct字段。

We could declare a get_name(&self) -> &str method on Trait and implement it on Foo and Bar , but that doesn't fix the problem of having duplicated code because both implementations of get_name will be the same. 我们可以在Trait上声明一个get_name(&self) -> &str方法,并在FooBar上实现它,但这不能解决重复代码的问题,因为get_name两种实现都是相同的。

It would be nice to avoid the code duplication. 最好避免代码重复。 Another question has already asked if field access is possible in traits, and the answer was basically "no". 另一个问题已经问到是否可以在性状中进行田间访问,而答案基本上是“否”。 However, I found a comment in the rust-internals forum suggesting that it's already possible. 但是,我在rust-internals论坛上发现了一条评论 ,暗示已经有可能。 Here's the code: 这是代码:

struct Fields {
    name: String,
}

trait Trait: BorrowMut<Fields> {
    // methods go here
}

impl<T> Trait for T where T: BorrowMut<Fields> {}

Presumably there's a way to make a type T be BorrowMut<Fields> and use that to allow Trait to access Fields 's fields, but so far I'm not sure how that would work. 大概有一种方法可以使T类型成为BorrowMut<Fields>并使用它来允许Trait访问Fields的字段,但是到目前为止,我不确定这将如何工作。

How is the code snippet shown above supposed to solve the problem of getting field access in traits? 上面显示的代码片段应如何解决在特征中获取字段访问的问题?


I know there are discussions of adding field access in traits to the language ( rust-internals , RFC , another RFC ), but I'd like to know what's possible now. 我知道有人在讨论将特质中的字段访问添加到该语言( rust-internalsRFC另一个RFC )中,但是我想知道现在有什么可能。

the answer was basically "no" 答案基本上是“否”

The answer actually says (emphasis mine): 答案实际上是(强调我的):

A default implementation can only use methods that are defined on the trait or in a super trait . 默认实现只能使用在特征或超级特征中定义的方法。

That's what your snippet does: 这就是您的代码段所做的:

trait Trait: BorrowMut<Fields>

To make it work, follow the advice from the post you are referencing: 要使其正常工作,请遵循您所引用的帖子中的建议:

all types which choose to implement BorrowMut<Foo> 选择实现BorrowMut<Foo>所有类型

Thus, you need to implement the trait for each of your types. 因此,您需要为每种类型实现特征。 I switched to Borrow because you don't need mutability here: 我切换到Borrow是因为这里不需要可变性:

use std::borrow::Borrow;

struct Fields {
    name: String,
}

trait Trait: Borrow<Fields> {
    fn show_name(&self) {
        let fields: &Fields = self.borrow();
        println!("{}", fields.name);
    }
}

struct Foo {
    fields: Fields,
    things_and_stuff: usize,
}

impl Borrow<Fields> for Foo {
    fn borrow(&self) -> &Fields {
        &self.fields
    }
}

struct Bar {
    fields: Fields,
    other_field: i32,
}

impl Borrow<Fields> for Bar {
    fn borrow(&self) -> &Fields {
        &self.fields
    }
}

impl<T> Trait for T where T: Borrow<Fields> {}

I'm almost certain you won't like this solution because it 我几乎可以肯定您不会喜欢这种解决方案,因为它

doesn't fix the problem of having duplicated code because both implementations [...] will be the same 不能解决重复代码的问题,因为两个实现都相同

You may prefer to write a macro if your goal is to reduce the number of duplicate characters in your code. 如果您的目标是减少代码中重复字符的数量,则可能更喜欢编写宏。

See also: 也可以看看:

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何将特征与使用特征的关联类型作为参数的超特征绑定? - How do I bound a trait with a supertrait that uses the trait's associated type as a parameter? 如何为特征的引用指定一个超特征? - How to specify a supertrait for the reference of a trait? 我如何在结构中有一个特征字段? - How do I have a trait field in a struct? trait upcast coercion workaround 是如何工作的(获取 supertrait 实例的 trait 方法)? - How does the trait upcast coercion workaround work (trait method for getting an instance of the supertrait)? 如何在Rust特征中添加Sized超级特征? - How to add a Sized supertrait to a Rust trait? 如何创建一个指定超特征关联类型的特征? - How to create a trait that specifies the associated type of a supertrait? 从 trait 方法返回对结构字段的可变引用时,如何修复生命周期不匹配? - How do I fix the lifetime mismatch when returning a mutable reference to the struct's field from a trait method? 当特征和结构使用相同的方法名称时,如何调用方法? - How to call a method when a trait and struct use the same method name? 是否可以从特征中访问结构字段? - Is it possible to access struct fields from within a trait? 当特征要求的状态多于结构所包含的状态时,如何为该结构实现特征? - How do I implement a trait for a struct when the trait requires more state than is contained in the struct?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM