Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/41.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Types 为什么';t向量<;T>;实现显示特性?_Types_Rust_Type Systems - Fatal编程技术网

Types 为什么';t向量<;T>;实现显示特性?

Types 为什么';t向量<;T>;实现显示特性?,types,rust,type-systems,Types,Rust,Type Systems,学习这门语言令我惊讶的是,我无法打印Vec: fn main() { let v1 = vec![1, 2, 3]; println!("{}", v1); } 错误[E0277]:`std::vec::vec`未实现`std::fmt::Display` -->src/main.rs:3:20 | 3 | println!(“{}”,v1); |^^`std::vec::vec`无法使用默认格式化程序格式化 | =help:trait'std::fmt::Display'未为

学习这门语言令我惊讶的是,我无法打印
Vec

fn main() {
    let v1 = vec![1, 2, 3];
    println!("{}", v1);
}
错误[E0277]:`std::vec::vec`未实现`std::fmt::Display`
-->src/main.rs:3:20
|
3 | println!(“{}”,v1);
|^^`std::vec::vec`无法使用默认格式化程序格式化
|
=help:trait'std::fmt::Display'未为'std::vec::vec'实现`
=注意:在格式字符串中,您可以使用`{:?}`(或{:#?}进行漂亮打印)
=注意:std::fmt::Display::fmt所需`

我可以理解这一点,并且我知道如何使用
{:?}
调试占位符。不幸的是,我还不明白为什么我不能这么做。对于C#或Haskell来说,这都是一项相当琐碎的任务,不是吗?对于任何可序列化(或可转换为字符串)的
T
,我将为
Vec
实现
Display
特性。我为什么不能那样做,我能有不同的解释吗?这是类型系统的一个限制吗?

首先,你不能为一个外来类型实现一个外来特性,这就是ker提供的问题和答案

原则上,没有什么可以阻止在定义了
Vec
的模块中实现
Display
(很可能在
collections::Vec
中)。然而,这是故意不做的。如和RFCs中所述,
显示
特性用于生成应向用户显示的字符串。然而,没有自然的方法从向量生成这样的字符串。您想要逗号分隔的项目还是制表符分隔的项目?它们应该用括号或花括号括起来,还是什么都不要?也许你想把每个元素打印在单独的行上?没有一条路可以走

解决这个问题的最简单方法是使用一个新类型的包装器。例如:

use std::fmt;

struct SliceDisplay<'a, T: 'a>(&'a [T]);

impl<'a, T: fmt::Display + 'a> fmt::Display for SliceDisplay<'a, T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let mut first = true;
        for item in self.0 {
            if !first {
                write!(f, ", {}", item)?;
            } else {
                write!(f, "{}", item)?;
            }
            first = false;
        }
        Ok(())
    }
}

fn main() {
    let items = vec![1, 2, 3, 4];
    println!("{}", SliceDisplay(&items));
}
使用std::fmt;
结构切片显示(&'a[T]);

impl fmt::SliceDisplay的显示您看到了吗?该问题还询问为什么不能为
Vec
实现
Display
,谢谢!不过,我还是不明白。为什么我需要一个额外的东西,比如
struct
,来实现一个trait呢?因为如果你可以,其他人也可以,那么你就有两个实现,编译器永远不知道该实现哪一个call@ker,如果当前crait中没有冲突的trait实现,为什么会出现问题?因为您的板条箱可能是一个库。然后有人可能会使用你的板条箱和另一个同样有impl的板条箱,最终得到两个impl。