当前位置: 首页 > 知识库问答 >
问题:

什么是'e::种::大小'没有实现的类型'自我'生锈?

公孙高畅
2023-03-14

这曾经奏效:

struct Foo<'a, T> {
  parent:&'a (Array<T> + 'a)
}

impl<'a, T> Foo<'a, T> { //'
  pub fn new<T>(parent:&Array<T>) -> Foo<T> {
    return Foo {
      parent: parent
    };
  }
}

trait Array<T> {
  fn as_foo(&self) -> Foo<T> {
    return Foo::new(self);
  }
}

fn main() {
}

现在它出现了错误:

:15:21:15:25错误:没有为类型Self:15 return Foo::new(Self)实现traitcore::gends::size

我可以猜出是什么问题;这是说我对Foo的建议

我不明白我所做的有什么不对,或者为什么不对?

例如,我应该(我想...)能够储存一个

playpen链接:http://is.gd/eZSZYv

共有1个答案

孙朗
2023-03-14

这里有两件事:特征对象强制(错误)和对象安全(修复它)。

正如错误消息所暗示的,代码中困难的部分是Foo::new(自己),这是因为pub fn new

trait Array {
  fn as_foo(&self) {
    let _ = self as &Array; // coerce to a trait object
  }
}

fn main() {}

同样的道理:

<anon>:3:13: 3:27 error: the trait `core::kinds::Sized` is not implemented for the type `Self`
<anon>:3     let _ = self as &Array; // coerce to a trait object
                     ^~~~~~~~~~~~~~

Self是实现该特征的类型的替代名称。与大多数通用参数不同,Self在默认情况下可能没有大小(?大小),因为RFC 546和#20341用于允许例如impl数组

变量self具有类型

出现错误是因为仅引用了

似乎合乎逻辑的是,我们正在寻找的修复方法是在我们想要执行强制时确保Self:Sized。这样做的明显方法是使Self始终size,即覆盖默认的?大小绑定如下:

trait Array: Sized {
  fn as_foo(&self) {
    let _ = self as &Array; // coerce to a trait object
  }
}

fn main() {}

看起来不错!

除了有一点不起作用;但至少这是出于不同的原因,我们正在取得进展!特征对象只能由“对象安全”的特征制成(即可以安全地制成特征对象),并且具有“大小”“自我”是破坏对象安全的事情之一:

<anon>:3:13: 3:17 error: cannot convert to a trait object because trait `Array` is not object-safe [E0038]
<anon>:3     let _ = self as &Array; // coerce to a trait object
                     ^~~~
<anon>:3:13: 3:17 note: the trait cannot require that `Self : Sized`
<anon>:3     let _ = self as &Array; // coerce to a trait object
                     ^~~~
<anon>:3:13: 3:17 note: the trait cannot require that `Self : Sized`
<anon>:3     let _ = self as &Array; // coerce to a trait object
                     ^~~~

(我以#20692的形式提交了该注释的双重打印。)

回到绘图板上。解决方案还有其他一些“简单”的可能性:

  • 定义一个扩展特性trait ArrayExt: SizedArray{fnas_foo(

然而,这些不一定适用于每个用例,例如,特定类型不能通过重载默认方法来定制行为。不过,还好有修复!

(以发现它的亚伦·图伦命名。)

使用广义的where子句,我们可以非常明确地知道Self应该在什么时候实施Sized,将其限制在需要的方法上,而不会影响其他特征:

trait Array {
  fn as_foo(&self) where Self: Sized {
    let _ = self as &Array; // coerce to a trait object
  }
}

fn main() {}

这个编译得很好!通过像这样使用where子句,编译器理解(a)强制是合法的,因为Self的大小是size,因此Self是一个细指针,并且(b)无论如何调用trait对象的方法是非法的,因此不会破坏对象安全性。若要查看它被禁止,请将的主体更改为\u foo

let x = self as &Array; // coerce to a trait object
x.as_foo();

给予

<anon>:4:7: 4:15 error: the trait `core::kinds::Sized` is not implemented for the type `Array`
<anon>:4     x.as_foo();
               ^~~~~~~~

正如预期的那样。

对原始未简化代码进行此更改同样简单,只需将where子句添加到as_foo方法中即可:

struct Foo<'a, T> { //'
  parent:&'a (Array<T> + 'a)
}

impl<'a, T> Foo<'a, T> {
  pub fn new(parent:&Array<T>) -> Foo<T> {
    return Foo {
      parent: parent
    };
  }
}

trait Array<T> {
  fn as_foo(&self) -> Foo<T> where Self: Sized {
    return Foo::new(self);
  }
}

fn main() {
}

编译没有错误。(NB.我不得不删除不必要的

(我有一些关于特质对象、对象安全和Turon技巧的正在进行中的博客文章,它们将在不久的将来出现在/r/rust上:第一篇。)

 类似资料:
  • 我希望这能奏效: ...但它没有: 游戏Geofence:http://is.gd/kxDt0P 那么,发生了什么事? 我不知道这个错误是什么意思。 是因为我使用的是Result,而这要求U,V不是大小的吗?在这种情况下,它们的尺寸为何?我没有写: 所有泛型现在都是动态调整大小还是什么?(在这种情况下,大小是什么?甚至是什么意思?) 怎么回事啊?

  • 问题内容: 说我有3个这样的课程: 难道那么有可能确定一个特定的对象是否是他的一个实例,或? 我认为这样的事情可能会起作用: 但是经过一点阅读之后,我认为它始终会被评为B,因为它只是测试强制转换是否有效,并且两者之间没有实质性差异。 问题答案: 做这个:

  • 元类型和? 做和返回一个? 我知道可以用来检查。你如何使用?

  • 我知道一个数据类型会自动提升到更高的数据类型byte-short-int

  • 在添加新的键值对时,我有几个关于重建哈希映射的问题。我将根据这些事实提出问题(它们对于Oracle JVM是正确的,不确定它们对于其他JVM是否正确): 每次当HashMap增长大于阈值(阈值=加载因子*条目数)时,Resize将重建HashMap,使其具有更大的内部表数组。新创建的条目放在哪个存储桶中并不重要,Map仍然会变得更大。即使所有条目都进入一个bucket(即它们的键“返回相同的数字)

  • Monoid函数的类型签名是: