无法从另一个板条箱为泛型类型从另一个板条箱实现特征 [英] Can not implement trait from another crate for generic type from another crate parameterized with local type

查看:31
本文介绍了无法从另一个板条箱为泛型类型从另一个板条箱实现特征的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个测试代码(playpen):

use std::fmt::{Display, Formatter, Error};

struct MyLocalType;

type MyResult = Result<MyLocalType, String>;

impl Display for MyResult {
    fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
        f.write_str("some test string")
    }
}

fn main() { 
    let r: MyResult = Ok(MyLocalType); 
    println!("{}" , r); 
}

产生此错误消息:

<anon>:7:1: 11:2 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]
<anon>:7 impl Display for MyResult {
<anon>:8     fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
<anon>:9         f.write_str("some test string")
<anon>:10     }
<anon>:11 }

这段代码在Rust的1月版本中成功编译;我现在该如何实施?

This code successfully compiled in the January version of Rust; how can I implement it now?

推荐答案

对于像 type 这样的纯别名,没有直接的方法可以解决这个问题.

There's no direct way to solve this for a pure alias like type.

代码与

impl Display for Result<MyLocalType, String>

并且编译器无法确保在其他 crate 中不会有冲突的实现(也就是说,无法确保实现是一致的").能够做到这一点有时肯定有用,但不幸的是,编译器之前接受了它.

and the compiler can't ensure that there will be no conflicting implementations in other crates (aka, can't ensure that the implementation is 'coherent'). Being able to do it is definitely useful sometimes, but it was unfortunately a bug that the compiler accepted it before.

解决方案包括:

  • Result 定义合适的包装器类型,例如struct MyResult(Result);,
  • 定义自己的枚举:enum MyResult { Ok(MyType), Err(String) },
  • 定义一个包装类型,但只在打印时使用,即写println!("{}", Wrapper(r)); 而不是println!("{}", r);.
  • defining a proper wrapper type for Result, e.g. struct MyResult(Result<MyLocalType, String>);,
  • defining your own enum: enum MyResult { Ok(MyType), Err(String) },
  • define a wrapper type, but only use it when printing, i.e. write println!("{}", Wrapper(r)); instead of println!("{}", r);.

这两者都使 MyResult 成为本地类型,因此 impl 应该是合法的.

Both of these make MyResult a local type, and so the impl then should be legal.

这篇关于无法从另一个板条箱为泛型类型从另一个板条箱实现特征的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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