将“impl From”参数转发到专门的函数

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

Forwarding `impl From` param to specialized function

问题

你有一些代码,希望创建一个函数,该函数可以接受实现了 From<(u32, u32)> 的内容,并将其传递给期望要么是 Foo 要么是 (u32, u32) 的函数。但你遇到了错误,因为没有实现 From<impl From<(u32, u32)>> 的 trait。要实现这个目标,你可以尝试以下方法:

pub fn print<T>(val: T)
where
    T: Into<Foo> + Into<(u32, u32)>,
{
    print_foo(val.into());
    print_tuple(val.into());
}

这个修改将函数 print 定义为一个泛型函数,可以接受任何类型 T,只要 T 实现了 Into<Foo>Into<(u32, u32)> 这两个 trait。这样,它就可以接受既可以转换为 Foo 也可以转换为 (u32, u32) 的类型。

希望这对你有所帮助。

英文:

So I have some type

#[derive(Debug)]
pub struct Foo {
    pub bar: u32,
    pub baz: u32,
}

impl From&lt;(u32, u32)&gt; for Foo {
    fn from(foo: (u32, u32)) -&gt; Self {
        Self {
            bar: foo.0,
            baz: foo.1,
        }
    }
}

My aim is to create a function that would receive something that implements From&lt;(u32, u32)&gt; and will forward it further to function expecting either Foo or (u32, u32). So it should be something like this

pub fn print(val: impl From&lt;(u32, u32)&gt;) {
    print_foo(val.into());
    print_tuple(val.into())
}

pub fn print_tuple(t: (u32, u32)) {
    println!(&quot;Tuple: {:?}&quot;, t);
}

pub fn print_foo(foo: Foo) {
    println!(&quot;Foo: {:?}&quot;, foo);
}

Unfortunately this will cause an error:

the trait `From&lt;impl From&lt;(u32, u32)&gt;&gt;` is not implemented for `Foo`
the trait `From&lt;impl From&lt;(u32, u32)&gt;&gt;` is not implemented for `(u32, u32)`

As I understand this wraps the impl From&lt;_&gt; with From due to into() call.

My question is how to reach the goal of having a function that can receive either tuple or struct that can be constructed from it and pass it further to specialized functions.

答案1

得分: 4

impl From<T> 是一个相当无用的类型来接收值,它可以是任何东西,但 From 允许我们做的只是创建的相同类型的项目,不能以任何有意义的方式使用我们已经拥有的值。相反,你想要的是使用 Into 的实现:

pub fn print<T: Into<(u32, u32)> + Into<Foo> + Clone>(val: T) {
    print_foo(val.clone().into());
    print_tuple(val.into())
}

注意,由于你想要传递相同的值两次,你必须添加 CopyClone 约束,或者要求 for<'a> &'a T: Into<Foo>

英文:

impl From&lt;T&gt; is a pretty useless type to receive values of, it could be anything but all that From lets us do is create new items of the same type, not use the value we have in any meaningful way. What you want instead is use an Into implementation:

pub fn print&lt;T: Into&lt;(u32, u32)&gt; + Into&lt;Foo&gt; + Clone&gt;(val: T) {
    print_foo(val.clone().into());
    print_tuple(val.into())
}

Note since you want to pass the same value twice you have to either add a Copy or Clone bound as well or require for&lt;&#39;a&gt; &amp;&#39;a T: Into&lt;Foo&gt; instead.

huangapple
  • 本文由 发表于 2023年4月7日 00:04:41
  • 转载请务必保留本文链接:https://go.coder-hub.com/75951562.html
匿名

发表评论

匿名网友

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

确定