从trait方法中只返回拥有权的类型,该方法可以接受所需的输入值作为拥有或借用。

4

我希望有一个特性,可以为T&T实现,但其方法始终返回T

我想要做的是像这样:

use std::borrow::ToOwned;

trait Foo<X: ToOwned> {
    fn f(&self, x: X) -> f64;
    
    fn g(&self) -> X::Owned;
}

struct Float(f64);

impl Foo<f64> for Float {
    fn f(&self, x: f64) -> f64 {
        x + self.0
    }
    
    fn g(&self) -> f64 {
        self.0 * 2.0
    }
}

struct List(Vec<f64>);

impl Foo<&Vec<f64>> for List {
    fn f(&self, x: &Vec<f64>) -> f64 {
        x.iter().sum()
    }
    
    // Error here - `&Vec<f64>` return type expected
    fn g(&self) -> Vec<f64> {
        self.0.iter().map(|&x| 2.0 * x).collect()
    }
}

fn main() {
    let float = Float(2.0);
    println!("{} {}", float.f(3.0), float.g());
   
    let list = List(vec![0.0, 1.0, 2.0]);
    println!("{} {:?}", list.f(&vec![1.0, 2.0]), list.g());
}

我知道一种选项是定义一个 trait 来指定输出类型,像这样:

trait FooReturn {
   type Output;
}

trait Foo<X: FooReturn> {
    fn f(&self, x: X) -> f64;

    fn g(&self) -> X::Output;
}

然后为所有相关类型实现该特质,但我想知道是否有更标准/健壮的方法来实现此操作。


&'static Vec<f64>&'a Vec<f64>::Owned 版本,它可以像这样编译。但这意味着您可能不想为此使用 ToOwned 特性。 - Hadus
好的。有没有内置特性可以满足我的需求?或者您认为我需要自己编写? - E. J. Winkleberry
我真的非常认为你不需要这个。它似乎并不是非常有用的东西。按值和按引用获取某些内容的行为是不同的。如果只是为了让你可以与数字等复制类型一起使用,那么按引用获取并在使用时取消引用可能会被优化掉。 - Hadus
1个回答

1
这是在专业化完成后的操作方式。而与此同时,在“1.55.0-nightly”版本上,我甚至无法编译一个简单的工作示例。
#![feature(specialization)]

trait MaybeOwned {
    type Owned;
}

default impl<X> MaybeOwned for X {
    type Owned = X;
}

impl<'a, X> MaybeOwned for &'a X {
    type Owned = X;
}

trait Foo<X: MaybeOwned> {
    fn f(&self, x: &X) -> f64;
    fn g(&self) -> <X as MaybeOwned>::Owned;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接