如何使用 std::convert::Into 转换可能失败的内容? [英] How can I use std::convert::Into to convert something that might fail?

查看:54
本文介绍了如何使用 std::convert::Into 转换可能失败的内容?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想要一个接受多种类型的函数,这些类型可以转换为我的特定类型.在类似的情况下,我会使用 std::convert::Into(或 std::convert::From):

pub struct MyThing;impl'a>进入<MyThing>对于 &'a str {fn into(self) ->我的东西 {我的东西}}fn main() {}

作为一个额外的问题,在我的特定情况下,转换可能会失败.通常,我会使用 Result 表示可能失败的操作.将两个概念结合在一起:

pub struct MyThing;酒吧结构错误;impl'a>进入<结果<MyThing, Error>>对于 &'a str {fn into(self) ->结果{如果 self.len() % 2 == 0 {好的(我的事情)} 别的 {错误(错误)}}}fn main() {}

不幸的是,这似乎违反了一致性规则:

error: impl 未引用此 crate 中定义的任何类型;只能实现当前 crate 中定义的特性任意类型 [E0117]

我发现我可以创建自己的特定特征:

struct MyThing;结构错误;特质 IntoMyThing {fn into(self) ->结果;}impl'a>IntoMyThing for &'a str {fn into(self) ->结果{如果 self.len() % 2 == 0 {好的(我的事情)} 别的 {错误(错误)}}}fn main() {}

甚至更通用的特征:

struct MyThing;结构错误;特质MaybeInto<T,E>{fn into(self) ->结果<T,E>;}impl'a>MaybeInto<MyThing, Error>对于 &'a str {fn into(self) ->结果{如果 self.len() % 2 == 0 {好的(我的事情)} 别的 {错误(错误)}}}fn main() {}

但是有没有办法重用标准库中的组件来实现我的目标?

解决方案

由于连贯性规则,这是不可能的,这使得这样的事情非常不方便,因为除非您创建新类型,否则您无法做到对于其中一种类型,Result&str.有关详细信息,请参阅 RFC #1023.

简而言之,根据该 RFC 规定的新规则,您不能为不是 crate 本地的类型实现不是 crate 本地的特征.

<块引用>

  1. 修改孤立规则,以便远程特征的实现需要一个本地类型,该类型要么是当前 crate 中定义的结构/枚举/特征 LT = LocalTypeConstructor<...> 或引用到本地类型 LT = ... |&LT |&mut LT.

因此,由于您没有在 crate 中创建 Into 特征,也没有在 Result 类型中创建,因此您会收到此错误.创建一个新类型可以解决这个问题,因为它基本上将非本地类型包装在本地类型中.

I would like a function that accepts a variety of types that can be converted to my specific type. In similar cases, I'd use std::convert::Into (or std::convert::From):

pub struct MyThing;

impl<'a> Into<MyThing> for &'a str {
    fn into(self) -> MyThing { 
        MyThing
    }
}

fn main() {}

As an extra wrinkle, in my specific case, the conversion can potentially fail. Normally, I'd use Result to represent an operation that may fail. Combining the two concepts together:

pub struct MyThing;
pub struct Error;

impl<'a> Into<Result<MyThing, Error>> for &'a str {
    fn into(self) -> Result<MyThing, Error> { 
        if self.len() % 2 == 0 {
            Ok(MyThing)
        } else {
            Err(Error)
        }
    }
}

fn main() {}

Unfortunately, this seems to run afoul of coherence rules:

error: the impl does not reference any types defined in this crate;
only traits defined in the current crate can be implemented for
arbitrary types [E0117]

I see that I could create my own specific trait:

struct MyThing;
struct Error;

trait IntoMyThing {
    fn into(self) -> Result<MyThing, Error>;
}

impl<'a> IntoMyThing for &'a str {
    fn into(self) -> Result<MyThing, Error> { 
        if self.len() % 2 == 0 {
            Ok(MyThing)
        } else {
            Err(Error)
        }
    }
}

fn main() {}

Or even a more-generic trait:

struct MyThing;
struct Error;

trait MaybeInto<T, E> {
    fn into(self) -> Result<T, E>;
}

impl<'a> MaybeInto<MyThing, Error> for &'a str {
    fn into(self) -> Result<MyThing, Error> { 
        if self.len() % 2 == 0 {
            Ok(MyThing)
        } else {
            Err(Error)
        }
    }
}

fn main() {}

But is there any way to reuse components from the standard library to accomplish my goal?

解决方案

This isn't possible as-is due to coherence rules, which makes things like this pretty inconvenient, because you can't do it unless you create a newtype for one of the types, either the Result or the &str. See RFC #1023 for more information.

In short, based on the new rules stipulated by that RFC, you cannot implement a trait that's not local to the crate for a type that's not local to the crate.

  1. Modify the orphan rules so that impls of remote traits require a local type that is either a struct/enum/trait defined in the current crate LT = LocalTypeConstructor<...> or a reference to a local type LT = ... | &LT | &mut LT.

So since you didn't create the Into trait in your crate nor the Result type, you get this error. Creating a new type fixes this because it basically wraps a non-local type in a local type.

这篇关于如何使用 std::convert::Into 转换可能失败的内容?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆