如何编写使IntoIter更通用的功能

时间:2019-06-23 20:55:12

标签: syntax rust type-bounds

我正在阅读关于stackoverflow问题的答案,并尝试修改函数history以使用IntoIter,其中item可以是任何可以转换为引用并具有某些特征Debug的东西。这种情况。

如果我要从函数定义中删除V: ?Sized,则锈编译器会抱怨说,它在编译时不知道str的大小。

use std::fmt::Debug;

pub fn history<I: IntoIterator, V: ?Sized>(i: I) where I::Item: AsRef<V>, V: Debug {
    for s in i {
        println!("{:?}", s.as_ref());
    }
}

fn main() {
    history::<_, str>(&["st", "t", "u"]);
}

我不明白为什么编译器首先显示错误,并且不确定如果我用V: ?Sized作弊,为什么程序可以正常工作。

1 个答案:

答案 0 :(得分:2)

  

我有点V: ?Sized作弊

这不是作弊。默认情况下,所有通用参数都假定为Sized。存在该默认值是因为它是最常见的情况-没有它,几乎每个类型参数都必须用: Sized注释。

在您的情况下,V只能通过引用进行访问,因此不需要Sized。放宽Sized约束可使您的函数尽可能地通用,从而使其可用于大多数类型。

类型str是无大小的,因此这不仅仅是泛化,实际上您需要放宽默认的Sized约束,以便能够将功能与str一起使用。