将返回 impl Trait 的存储函数作为 trait 对象

huangapple go评论67阅读模式
英文:

Store function returning impl Trait as trait object

问题

根据下面的示例,我正在尝试将函数存储为特征对象。我已经弄清楚了如何对返回具体类型的函数执行此操作,方法是使用 as 将函数项转换为函数指针。然而,我也想存储返回 impl Element 的函数在 Vector 中,就我所了解的而言,这需要在 HasChildren 实现中使用泛型参数,但接下来我不知道该如何或应该将其转换为什么,以便将其用作特征对象。

trait Element {}
trait HasChildren {}

struct Foo {}
impl Element for Foo {}
impl HasChildren for Foo {}

impl HasChildren for fn(String) -> Foo {}
impl<E: Element> HasChildren for fn(i32) -> E {}

fn get_concrete_element(val: String) -> Foo {
    Foo {}
}

fn get_impl_element(val: i32) -> impl Element {
    Foo {}
}

fn main() {
    // 在 Vec 中存储各种特征对象
    let mut data: Vec<Box<dyn HasChildren>> = Vec::new();
    data.push(Box::new(Foo {})); // 工作正常
    data.push(Box::new(get_concrete_element as fn(String) -> Foo)); // 工作正常
    data.push(Box::new(get_impl_element as fn(i32) -> impl Element)); // 不工作
}
英文:

As per the below example, I am trying to store functions as trait objects. I have worked out how to do this for functions which return a concrete type, by using as to cast from a function item to a function pointer. However, I would also like to store functions that return impl Element in the Vector, which as far as I understand requires using a generic parameter in the HasChildren implementation, but then I don't know how or what I should cast it to so it can be used as a trait object.

trait Element {}
trait HasChildren {}

struct Foo {}
impl Element for Foo {}
impl HasChildren for Foo {}

impl HasChildren for fn(String) -&gt; Foo {}
impl&lt;E: Element&gt; HasChildren for fn(i32) -&gt; E {}

fn get_concrete_element(val: String) -&gt; Foo {
    Foo {}
}

fn get_impl_element(val: i32) -&gt; impl Element {
    Foo {}
}

fn main() {
    // Store various trait objects in Vec
    let mut data: Vec&lt;Box&lt;dyn HasChildren&gt;&gt; = Vec::new();
    data.push(Box::new(Foo {})); // works
    data.push(Box::new(get_concrete_element as fn(String) -&gt; Foo)); // works
    data.push(Box::new(get_impl_element as fn(i32) -&gt; impl Element)); // doesn&#39;t work
}

答案1

得分: 2

你不能指定返回类型的名称,但你可以让编译器推断它:
```rust
data.push(Box::new(get_impl_element as fn(i32) -> _));
英文:

You cannot name the return type, but you can let the compiler infer it:

data.push(Box::new(get_impl_element as fn(i32) -&gt; _));

huangapple
  • 本文由 发表于 2023年7月10日 19:36:51
  • 转载请务必保留本文链接:https://go.coder-hub.com/76653343.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定