这曾经奏效:
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
这里有两件事:特征对象强制(错误)和对象安全(修复它)。
正如错误消息所暗示的,代码中困难的部分是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函数的类型签名是: