如何更普遍地编写采用 IntoIter 的函数
How to write fuctions that takes IntoIter more generally
我正在阅读 Whosebug 问题的答案并尝试修改函数 history
以采用 IntoIter
其中项目可以是任何可以转换为参考并具有某些特征的东西 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
.
作弊程序为什么能正常工作
I kind of cheat with V: ?Sized
这不是作弊。默认情况下,所有通用参数都假定为 Sized
。这个默认值存在是因为它是最常见的情况——没有它,几乎每个类型参数都必须用 : Sized
.
注释
在你的例子中,V
只能通过引用访问,所以它不需要是 Sized
。放宽 Sized
约束使您的函数尽可能通用,允许它与大多数可能的类型一起使用。
类型 str
未调整大小,因此这不仅仅是泛化,您实际上需要放宽默认 Sized
约束才能将您的函数与 str
一起使用。
我正在阅读 Whosebug 问题的答案并尝试修改函数 history
以采用 IntoIter
其中项目可以是任何可以转换为参考并具有某些特征的东西 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
.
I kind of cheat with
V: ?Sized
这不是作弊。默认情况下,所有通用参数都假定为 Sized
。这个默认值存在是因为它是最常见的情况——没有它,几乎每个类型参数都必须用 : Sized
.
在你的例子中,V
只能通过引用访问,所以它不需要是 Sized
。放宽 Sized
约束使您的函数尽可能通用,允许它与大多数可能的类型一起使用。
类型 str
未调整大小,因此这不仅仅是泛化,您实际上需要放宽默认 Sized
约束才能将您的函数与 str
一起使用。