带别名的锈迹尺寸错误-为什么会发生这种情况?

问题描述 投票:-1回答:1

我有这样的功能:

fn edit0<S: AsRef<str>>(&self, w: S) -> Stream<String> {
    let owned_word = w.as_ref().to_string();
    let g = Gn::new_scoped(|mut s| {
        s.yield_(owned_word);
        done!();
    });
    return g;
}

此编译正常。

现在,如果我输入通用参数的别名,就像这样:

type Word = dyn AsRef<str>;

fn edit0(&self, w: Word) -> Stream<String> {
    let owned_word = w.as_ref().to_string();
    let g = Gn::new_scoped(|mut s| {
        s.yield_(owned_word);
        done!();
    });
    return g;
}

我收到一个错误的说法:

 fn edit0(&self, w: Word) -> Stream<String> {
   |                     ^ doesn't have a size known at compile-time
   |
   = help: the trait `std::marker::Sized` is not implemented for `(dyn std::convert::AsRef<str> + 'static)`
   = note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
   = note: all local variables must have a statically known size
   = help: unsized locals are gated as an unstable feature

为什么会这样?

rust size type-alias
1个回答
1
投票

edit0方法需要在编译时知道其参数的大小。但是,您使用的变量w是类型AsRef<str>的特征对象,并且其大小无法在编译时确定。相反,您有2个选择:

  1. 将指针传递到特征对象
  2. 将引用传递给特征对象

您可以如下使用Box传递指针:

fn edit0(&self, w: Box<Word>) -> Stream<String>

或以下参考:

fn edit0(&self, w: &Word) -> Stream<String>

另一种选择是避免完全使用特征对象。您可以改为使edit0成为通用方法,如下所示:

fn edit0(&self, w: impl AsRef<str>) -> Stream<String>

fn edit0<W: AsRef<str>>(&self, w: W) -> Stream<String>

使用这种方法,编译器执行所谓的“单态化”,即在编译时准确确定要为您的泛型参数传递哪种类型,并为每个调用生成多个非泛型函数。 this SO question

中很好地解释了同质化
© www.soinside.com 2019 - 2024. All rights reserved.