首页 > 解决方案 > 如何编写更通用的 IntoIter 函数

问题描述

我正在阅读 stackoverflow 问题的答案,并尝试修改函数history以获取IntoIteritem 可以是任何可以转换为参考并且Debug在这种情况下具有一些特征的东西。

如果我V: ?Sized从函数定义中删除,rust 编译器会抱怨它不知道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.

标签: syntaxrusttype-bounds

解决方案


我有点欺骗V: ?Sized

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

在您的情况下,V只能通过引用访问,所以它不需要是Sized. 放宽Sized约束使您的函数尽可能通用,允许它与最可能的类型一起使用。

类型str没有大小,所以这不仅仅是泛化,你实际上需要放宽默认Sized约束才能使用你的函数str


推荐阅读