是否有可能为一个特征创建一个通用的实现,它适用于除一个类型子集之外的所有类型?
Is it possible to create a generic impl for a trait that works with all but one subset of types?
我正在尝试编写一个通用方法,该方法接受 returns Serialize
值或 Arc<Serialize>
值的函数。我的解决方案是创建一个特征来在需要时展开 Arc
并生成对基础值的引用:
use serde::Serialize;
use std::sync::Arc;
pub trait Unwrapper {
type Inner: Serialize;
fn unwrap(&self) -> &Self::Inner;
}
impl<T> Unwrapper for T
where
T: Serialize,
{
type Inner = T;
fn unwrap(&self) -> &Self::Inner {
self
}
}
impl<T> Unwrapper for Arc<T>
where
T: Serialize,
{
type Inner = T;
fn unwrap(&self) -> &Self::Inner {
self
}
}
fn use_processor<F, O>(processor: F)
where
O: Unwrapper,
F: Fn() -> O,
{
// do something useful processor
}
我收到一个 E0119
错误,因为 Arc
将来可能会实现 Serialize
,就像我启用 serde crate 的功能以允许那样:
error[E0119]: conflicting implementations of trait `Unwrapper` for type `std::sync::Arc<_>`:
--> src/lib.rs:20:1
|
10 | / impl<T> Unwrapper for T
11 | | where
12 | | T: Serialize,
13 | | {
... |
17 | | }
18 | | }
| |_- first implementation here
19 |
20 | / impl<T> Unwrapper for Arc<T>
21 | | where
22 | | T: Serialize,
23 | | {
... |
27 | | }
28 | | }
| |_^ conflicting implementation for `std::sync::Arc<_>`
我不想这样做,因为我只想在顶层允许 Arc
而不是在值内(出于同样的原因,默认情况下不启用该功能)。鉴于此,有没有办法仅针对 Arc
禁用我的第一个 impl
?或者有更好的方法来解决这个问题吗?
您的尝试无效,因为
特征的实现不可能重叠。
下面尝试编写接受 Serialize
值或
Arc
的 Serialize
值。
它利用 Borrow
特性及其对任何 T 的全面实施。
注意在泛型方法的调用站点上使用 turbo fish 语法。
use std::sync::Arc;
use std::borrow::Borrow;
use serde::Serialize;
#[derive(Serialize, Debug)]
struct Point {
x: i32,
y: i32,
}
fn myserialize<T: Borrow<I>, I: Serialize>(value: T) {
let value = value.borrow();
let serialized = serde_json::to_string(value).unwrap();
println!("serialized = {}", serialized);
}
fn main() {
let point = Point { x: 1, y: 2 };
myserialize(point);
let arc_point = Arc::new(Point { x: 1, y: 2 });
myserialize::<_, Point>(arc_point);
}
我正在尝试编写一个通用方法,该方法接受 returns Serialize
值或 Arc<Serialize>
值的函数。我的解决方案是创建一个特征来在需要时展开 Arc
并生成对基础值的引用:
use serde::Serialize;
use std::sync::Arc;
pub trait Unwrapper {
type Inner: Serialize;
fn unwrap(&self) -> &Self::Inner;
}
impl<T> Unwrapper for T
where
T: Serialize,
{
type Inner = T;
fn unwrap(&self) -> &Self::Inner {
self
}
}
impl<T> Unwrapper for Arc<T>
where
T: Serialize,
{
type Inner = T;
fn unwrap(&self) -> &Self::Inner {
self
}
}
fn use_processor<F, O>(processor: F)
where
O: Unwrapper,
F: Fn() -> O,
{
// do something useful processor
}
我收到一个 E0119
错误,因为 Arc
将来可能会实现 Serialize
,就像我启用 serde crate 的功能以允许那样:
error[E0119]: conflicting implementations of trait `Unwrapper` for type `std::sync::Arc<_>`:
--> src/lib.rs:20:1
|
10 | / impl<T> Unwrapper for T
11 | | where
12 | | T: Serialize,
13 | | {
... |
17 | | }
18 | | }
| |_- first implementation here
19 |
20 | / impl<T> Unwrapper for Arc<T>
21 | | where
22 | | T: Serialize,
23 | | {
... |
27 | | }
28 | | }
| |_^ conflicting implementation for `std::sync::Arc<_>`
我不想这样做,因为我只想在顶层允许 Arc
而不是在值内(出于同样的原因,默认情况下不启用该功能)。鉴于此,有没有办法仅针对 Arc
禁用我的第一个 impl
?或者有更好的方法来解决这个问题吗?
您的尝试无效,因为 特征的实现不可能重叠。
下面尝试编写接受 Serialize
值或
Arc
的 Serialize
值。
它利用 Borrow
特性及其对任何 T 的全面实施。
注意在泛型方法的调用站点上使用 turbo fish 语法。
use std::sync::Arc;
use std::borrow::Borrow;
use serde::Serialize;
#[derive(Serialize, Debug)]
struct Point {
x: i32,
y: i32,
}
fn myserialize<T: Borrow<I>, I: Serialize>(value: T) {
let value = value.borrow();
let serialized = serde_json::to_string(value).unwrap();
println!("serialized = {}", serialized);
}
fn main() {
let point = Point { x: 1, y: 2 };
myserialize(point);
let arc_point = Arc::new(Point { x: 1, y: 2 });
myserialize::<_, Point>(arc_point);
}