【问题标题】:How to write fuctions that takes IntoIter more generally如何编写更一般地采用 Into_Iter 的函数
【发布时间】:2019-06-23 20:55:12
【问题描述】:

我正在阅读 stackoverflow 问题的答案并尝试修改函数 history 以采用 IntoIter 其中 item 可以是任何可以转换为引用的东西,并且在这种情况下具有一些特征 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 作弊,我不确定为什么程序可以正常工作。

【问题讨论】:

    标签: syntax rust type-bounds


    【解决方案1】:

    我有点欺骗V: ?Sized

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

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

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

    【讨论】:

      猜你喜欢
      • 2017-02-12
      • 1970-01-01
      • 2012-02-14
      • 1970-01-01
      • 1970-01-01
      • 2016-06-06
      • 1970-01-01
      • 2015-02-21
      • 1970-01-01
      相关资源
      最近更新 更多