gpt4 book ai didi

rust - 是否可以提供可链接特征方法的默认实现?

转载 作者:行者123 更新时间:2023-12-03 11:41:32 26 4
gpt4 key购买 nike

目标是拥有类似于 (playground) 的东西:

trait T {
fn get_mutable_attribute(&mut self) -> &mut String;
fn forwardable_append_attribute(mut self, new_value: &str) -> Self {
let attribute = self.get_mutable_attribute();
attribute.push_str(new_value);
println!("{}", attribute);
self
}
}

struct S {
attribute: String,
}

impl T for S {
fn get_mutable_attribute(&mut self) -> &mut String {
&mut self.attribute
}
}

fn main() {
let s = S {
attribute: "init".to_string(),
}
.forwardable_append_attribute("new_1")
.forwardable_append_attribute("new_2")
.forwardable_append_attribute("new_3");
}
这给出了错误:
error[E0277]: the size for values of type `Self` cannot be known at compilation time
--> src/main.rs:3:37
|
3 | fn forwardable_append_attribute(mut self, new_value: &str) -> Self {
| ^^^^^^^^ doesn't have a size known at compile-time
|
= help: unsized locals are gated as an unstable feature
help: consider further restricting `Self`
|
3 | fn forwardable_append_attribute(mut self, new_value: &str) -> Self where Self: std::marker::Sized {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: function arguments must have a statically known size, borrowed types always have a known size
|
3 | fn forwardable_append_attribute(&mut self, new_value: &str) -> Self {
| ^
另一种方法是为实现特征的每个对象定义特征方法,但会在所有子对象( playground )之间引入重复:
trait T {
fn get_mutable_attribute(&mut self) -> &mut String;
fn forwardable_append_attribute(self, new_value: &str) -> Self;
}

struct S {
attribute: String,
}

impl T for S {
fn get_mutable_attribute(&mut self) -> &mut String {
&mut self.attribute
}
fn forwardable_append_attribute(mut self, new_value: &str) -> Self {
let attribute = self.get_mutable_attribute();
attribute.push_str(new_value);
println!("{}", attribute);
self
}
}

fn main() {
let s = S {
attribute: "init".to_string(),
}
.forwardable_append_attribute("new_1")
.forwardable_append_attribute("new_2")
.forwardable_append_attribute("new_3");
}

最佳答案

It's complaining that you can't return self , since self might not be Sized .因此,您只需添加 Self 的边界即可必须是 Sized关于方法:

trait T {
fn get_mutable_attribute(&mut self) -> &mut String;
fn forwardable_append_attribute(mut self, new_value: &str) -> Self
// note this trait bound
where
Self: Sized,
{
let attribute = self.get_mutable_attribute();
attribute.push_str(new_value);
println!("{}", attribute);
self
}
}

struct S {
attribute: String,
}

impl T for S {
fn get_mutable_attribute(&mut self) -> &mut String {
&mut self.attribute
}
}

fn main() {
let s = S {
attribute: "init".to_string(),
}
.forwardable_append_attribute("new_1")
.forwardable_append_attribute("new_2")
.forwardable_append_attribute("new_3");
}
请注意,您也可以将 Sized绑定(bind)在特征本身而不是方法上,看起来像 trait T: Sized {...} .如果 trait 只提供可链接方法,则应该这样做,因此为不能具有可链接方法的类型实现 trait 是没有意义的。或者,不要移动 self在函数中,您可以获取可变引用并返回可变引用,无需 Sized :
trait T {
fn get_mutable_attribute(&mut self) -> &mut String;
// note the &mut self and &mut Self
fn forwardable_append_attribute(&mut self, new_value: &str) -> &mut Self {
let attribute = self.get_mutable_attribute();
attribute.push_str(new_value);
println!("{}", attribute);
self
}
}

struct S {
attribute: String,
}

impl T for S {
fn get_mutable_attribute(&mut self) -> &mut String {
&mut self.attribute
}
}

fn main() {
let s = S {
attribute: "init".to_string(),
}
.forwardable_append_attribute("new_1")
.forwardable_append_attribute("new_2")
.forwardable_append_attribute("new_3");
}

关于rust - 是否可以提供可链接特征方法的默认实现?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64858403/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com