rust - 如何使 trait 方法采用 &Self 参数
问题描述
我正在尝试使用一些默认方法实现来创建特征。其中一种方法必须采用相同类型的实例并执行一些计算。
这是我要实现的简单示例:
struct A {
val: f32,
}
trait S {
fn val(&self) -> f32;
fn add(&self, other: &Self) -> f32 {
add(&self, other)
}
}
impl S for A {
fn val(&self) -> f32 {
self.val
}
}
fn add<T: S>(first: &T, second: &T) -> f32 {
first.val() + second.val()
}
这无法编译并出现错误:
15 | | fn add(&self, other: &Self) -> f32 {
16 | | add(&self, other)
| | ^^^^^ expected `&Self`, found type parameter `Self`
17 | | }
我不明白错误信息,因为 other 是&Self
not类型Self
,那么为什么编译器会不这么认为呢?
如果我将其更改为引用add(&self, &other)
(这似乎不正确,因为other
已经是引用类型),我会收到另一个错误:
|
16 | add(&self, &other)
| ^^^ the trait `S` is not implemented for `&Self`
...
26 | fn add<T: S>(first: &T, second: &T) -> f32 {
| - required by this bound in `add`
有没有办法通过默认特征实现来实现这一点,或者这只适用于具体类型(比如这个问题:如何实现 Add trait for a reference to a struct?)?
编辑:如果我称它为add(self, other)
,它会尝试发送特征对象,但我想通过引用发送对象。真的,我想发送具体的实现而不是特征对象。
error[E0277]: the size for values of type `Self` cannot be known at compilation time
--> src/main.rs:16:9
|
16 | add(self, other)
| ^^^ doesn't have a size known at compile-time
解决方案
您正在传递&self
给add()
,这使其成为双重引用,并且参数add()
类型不一致。T
ofadd
显然是由第一个参数决定的,这就是为什么编译器似乎期望另一个参数也有参数的原因&&Self
。(阅读错误消息末尾的注释。)
调用它,add(self, other)
它会编译。请注意,您还需要通过添加来选择退出隐式Sized
绑定。add
+ ?Sized
// rest as in your code
trait S {
fn val(&self) -> f32;
fn add(&self, other: &Self) -> f32 {
add(self, other)
}
}
fn add<T: S + ?Sized>(first: &T, second: &T) -> f32 {
first.val() + second.val()
}
推荐阅读
- swift - 使用加密类快速实现 SOLID 原则
- android - 如何将JSON数据解析成android?
- java - 使用 OAuth 2.0 授权访问 Google 表格
- module - Prestashop 1.7 向订单表添加新列
- mysql - mysql转储文件和binlog不一致
- c++ - 这个 c++ 向量初始化会导致内存泄漏吗?
- html - 列中可独立滚动的 DIV
- sql - MS Access 中的数据宏不适用于来自 JAVA 的 SQL 查询
- javascript - 如何延迟在 [(ngModel)] 中获取数据?
- sql - 检查从数据库返回的所有记录,以查看某些记录是否符合条件。如果没有,则过滤掉这些记录