'static: std::marker::Sized` 不满意 - 我需要 Box 吗?
'static: std::marker::Sized` is not satisfied - do I need to Box?
我即将给出一个特征作为参数,通过一个名为 new
.
的构造方法来存储它
结构类型的特征在此处作为参数给出:
渲染器.rs
use super::shapes::Shape;
pub struct Renderer;
impl Renderer{
pub fn set_shape<T : Shape>(&self, shape: T) -> T::Builder{
T::Builder::new(shape)
}
}
则调用关联类型指定的Builder
的构造函数
shapebuilder.rs
use super::shapes::Shape;
use super::shapes::Rectangle;
pub trait ShapeBuilder{
fn new<T:Shape>(shape: T) -> Self;
}
pub struct RectangleBuilder{
shape: Shape<Builder=RectangleBuilder>
}
impl ShapeBuilder for RectangleBuilder{
fn new<T:Shape>(shape: T) -> Self{
RectangleBuilder{
shape: shape as Rectangle
}
}
}
此时我已经想指出编译输出
compiler_output
error[E0277]: the trait bound `shapes::Shape<Builder=shapebuilder::RectangleBuilder> + 'static: std::marker::Sized` is not satisfied
--> shapes.rs:14:6
|
14 | impl Shape for Rectangle{
| ^^^^^
|
= note: `shapes::Shape<Builder=shapebuilder::RectangleBuilder> + 'static` does not have a constant size known at compile-time
= note: required because it appears within the type `shapebuilder::RectangleBuilder`
= note: required by `shapes::Shape`
error: aborting due to previous error
我在 SO 上发现了类似的问题,它讲述了一些关于拳击的事情。我试图对每个参数类型进行 Box 来解决这个问题。装箱成这样shape: Box<T>
。没有成功。我需要装箱吗?我理解编译器无法解析特征大小的问题,因为 specific/concrete 结构类型可以根据其 field/properties 具有不同的大小。我仍然无法找到解决方案。希望这是微不足道的。
为了完整性列出了未涉及的模块(我的意见)
shapes.rs
use super::shapebuilder::ShapeBuilder;
use super::shapebuilder::RectangleBuilder;
pub trait Shape{
type Builder: ShapeBuilder;
}
#[derive(Clone, Copy)]
pub struct Rectangle{
pub height: usize,
pub width: usize,
}
impl Shape for Rectangle{
type Builder = RectangleBuilder;
}
lib.rs
pub mod renderer;
mod shapes;
mod shapebuilder;
好吧,编译器并没有真正指出错误的根源。问题在这里:
pub struct RectangleBuilder {
shape: Shape<Builder=RectangleBuilder>
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this is an unsized type!
}
Shape
是一个特征,将其用作类型会产生未调整大小的类型。我们可以将其装箱以修复此错误:
pub struct RectangleBuilder {
shape: Box<Shape<Builder=RectangleBuilder>>
}
但是,我们如何处理这里的演员表?
impl ShapeBuilder for RectangleBuilder {
fn new<T: Shape>(shape: T) -> Self {
RectangleBuilder {
shape: shape as Rectangle
// ^^^^^^^^^^^^^^^^^^ can't cast a generic type!
}
}
}
如果 RectangleBuilder
确实准备好接受 Builder
为 RectangleBuilder
的任何 Shape
,那么让我们删除转换并在必要时添加适当的约束。
pub mod renderer {
use super::shapes::Shape;
use super::shapebuilder::ShapeBuilder;
pub struct Renderer;
impl Renderer {
pub fn set_shape<T: Shape + 'static>(&self, shape: T) -> T::Builder {
T::Builder::new(shape)
}
}
}
mod shapes {
use super::shapebuilder::ShapeBuilder;
use super::shapebuilder::RectangleBuilder;
pub trait Shape {
type Builder: ShapeBuilder;
}
#[derive(Clone, Copy)]
pub struct Rectangle {
pub height: usize,
pub width: usize,
}
impl Shape for Rectangle {
type Builder = RectangleBuilder;
}
}
mod shapebuilder {
use super::shapes::Shape;
pub trait ShapeBuilder: Sized {
fn new<T: Shape<Builder=Self> + 'static>(shape: T) -> Self;
}
pub struct RectangleBuilder {
shape: Box<Shape<Builder=RectangleBuilder> + 'static>,
}
impl ShapeBuilder for RectangleBuilder {
fn new<T: Shape<Builder=Self> + 'static>(shape: T) -> Self {
RectangleBuilder {
shape: Box::new(shape)
}
}
}
}
'static
绑定限制了可以存储在特定 Shape
实例中的引用。 'static
表示实现不能包含引用,除非它们具有 'static
生命周期。
但是,如果您需要在 RectangleBuilder
中使用 Rectangle
的字段,那么 RectangleBuilder
应该只接受 Rectangle
,而不是任何形状。我们可以再次使用关联类型来表达这一点。
pub mod renderer {
use super::shapes::Shape;
use super::shapebuilder::ShapeBuilder;
pub struct Renderer;
impl Renderer {
pub fn set_shape<T: Shape>(&self, shape: T) -> T::Builder {
T::Builder::new(shape)
}
}
}
mod shapes {
use super::shapebuilder::ShapeBuilder;
use super::shapebuilder::RectangleBuilder;
pub trait Shape {
type Builder: ShapeBuilder<Shape=Self>;
}
#[derive(Clone, Copy)]
pub struct Rectangle {
pub height: usize,
pub width: usize,
}
impl Shape for Rectangle {
type Builder = RectangleBuilder;
}
}
mod shapebuilder {
use super::shapes::Shape;
use super::shapes::Rectangle;
pub trait ShapeBuilder: Sized {
type Shape: Shape + ?Sized;
fn new(shape: Self::Shape) -> Self;
}
pub struct RectangleBuilder {
shape: Rectangle,
}
impl ShapeBuilder for RectangleBuilder {
type Shape = Rectangle;
fn new(shape: Self::Shape) -> Self {
RectangleBuilder {
shape: shape
}
}
}
}
在 ShapeBuilder
中,我们添加了一个 Shape
关联类型,指定每个 ShapeBuilder
将操作的 Shape
类型。 ShapeBuilder::new
现在使用此关联类型而不是类型参数来指定其操作数的类型。请注意,+ ?Sized
边界是必需的,因为否则会有一个隐式的 + Sized
边界,并且 Rust 抱怨 Shape
并不意味着 Sized
。解决此问题的另一种方法是将 : Sized
添加到 Shape
的定义中。
pub trait Shape: Sized {
type Builder: ShapeBuilder<Shape=Self>;
}
我即将给出一个特征作为参数,通过一个名为 new
.
结构类型的特征在此处作为参数给出:
渲染器.rs
use super::shapes::Shape;
pub struct Renderer;
impl Renderer{
pub fn set_shape<T : Shape>(&self, shape: T) -> T::Builder{
T::Builder::new(shape)
}
}
则调用关联类型指定的Builder
的构造函数
shapebuilder.rs
use super::shapes::Shape;
use super::shapes::Rectangle;
pub trait ShapeBuilder{
fn new<T:Shape>(shape: T) -> Self;
}
pub struct RectangleBuilder{
shape: Shape<Builder=RectangleBuilder>
}
impl ShapeBuilder for RectangleBuilder{
fn new<T:Shape>(shape: T) -> Self{
RectangleBuilder{
shape: shape as Rectangle
}
}
}
此时我已经想指出编译输出
compiler_output
error[E0277]: the trait bound `shapes::Shape<Builder=shapebuilder::RectangleBuilder> + 'static: std::marker::Sized` is not satisfied
--> shapes.rs:14:6
|
14 | impl Shape for Rectangle{
| ^^^^^
|
= note: `shapes::Shape<Builder=shapebuilder::RectangleBuilder> + 'static` does not have a constant size known at compile-time
= note: required because it appears within the type `shapebuilder::RectangleBuilder`
= note: required by `shapes::Shape`
error: aborting due to previous error
我在 SO 上发现了类似的问题,它讲述了一些关于拳击的事情。我试图对每个参数类型进行 Box 来解决这个问题。装箱成这样shape: Box<T>
。没有成功。我需要装箱吗?我理解编译器无法解析特征大小的问题,因为 specific/concrete 结构类型可以根据其 field/properties 具有不同的大小。我仍然无法找到解决方案。希望这是微不足道的。
为了完整性列出了未涉及的模块(我的意见)
shapes.rs
use super::shapebuilder::ShapeBuilder;
use super::shapebuilder::RectangleBuilder;
pub trait Shape{
type Builder: ShapeBuilder;
}
#[derive(Clone, Copy)]
pub struct Rectangle{
pub height: usize,
pub width: usize,
}
impl Shape for Rectangle{
type Builder = RectangleBuilder;
}
lib.rs
pub mod renderer;
mod shapes;
mod shapebuilder;
好吧,编译器并没有真正指出错误的根源。问题在这里:
pub struct RectangleBuilder {
shape: Shape<Builder=RectangleBuilder>
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this is an unsized type!
}
Shape
是一个特征,将其用作类型会产生未调整大小的类型。我们可以将其装箱以修复此错误:
pub struct RectangleBuilder {
shape: Box<Shape<Builder=RectangleBuilder>>
}
但是,我们如何处理这里的演员表?
impl ShapeBuilder for RectangleBuilder {
fn new<T: Shape>(shape: T) -> Self {
RectangleBuilder {
shape: shape as Rectangle
// ^^^^^^^^^^^^^^^^^^ can't cast a generic type!
}
}
}
如果 RectangleBuilder
确实准备好接受 Builder
为 RectangleBuilder
的任何 Shape
,那么让我们删除转换并在必要时添加适当的约束。
pub mod renderer {
use super::shapes::Shape;
use super::shapebuilder::ShapeBuilder;
pub struct Renderer;
impl Renderer {
pub fn set_shape<T: Shape + 'static>(&self, shape: T) -> T::Builder {
T::Builder::new(shape)
}
}
}
mod shapes {
use super::shapebuilder::ShapeBuilder;
use super::shapebuilder::RectangleBuilder;
pub trait Shape {
type Builder: ShapeBuilder;
}
#[derive(Clone, Copy)]
pub struct Rectangle {
pub height: usize,
pub width: usize,
}
impl Shape for Rectangle {
type Builder = RectangleBuilder;
}
}
mod shapebuilder {
use super::shapes::Shape;
pub trait ShapeBuilder: Sized {
fn new<T: Shape<Builder=Self> + 'static>(shape: T) -> Self;
}
pub struct RectangleBuilder {
shape: Box<Shape<Builder=RectangleBuilder> + 'static>,
}
impl ShapeBuilder for RectangleBuilder {
fn new<T: Shape<Builder=Self> + 'static>(shape: T) -> Self {
RectangleBuilder {
shape: Box::new(shape)
}
}
}
}
'static
绑定限制了可以存储在特定 Shape
实例中的引用。 'static
表示实现不能包含引用,除非它们具有 'static
生命周期。
但是,如果您需要在 RectangleBuilder
中使用 Rectangle
的字段,那么 RectangleBuilder
应该只接受 Rectangle
,而不是任何形状。我们可以再次使用关联类型来表达这一点。
pub mod renderer {
use super::shapes::Shape;
use super::shapebuilder::ShapeBuilder;
pub struct Renderer;
impl Renderer {
pub fn set_shape<T: Shape>(&self, shape: T) -> T::Builder {
T::Builder::new(shape)
}
}
}
mod shapes {
use super::shapebuilder::ShapeBuilder;
use super::shapebuilder::RectangleBuilder;
pub trait Shape {
type Builder: ShapeBuilder<Shape=Self>;
}
#[derive(Clone, Copy)]
pub struct Rectangle {
pub height: usize,
pub width: usize,
}
impl Shape for Rectangle {
type Builder = RectangleBuilder;
}
}
mod shapebuilder {
use super::shapes::Shape;
use super::shapes::Rectangle;
pub trait ShapeBuilder: Sized {
type Shape: Shape + ?Sized;
fn new(shape: Self::Shape) -> Self;
}
pub struct RectangleBuilder {
shape: Rectangle,
}
impl ShapeBuilder for RectangleBuilder {
type Shape = Rectangle;
fn new(shape: Self::Shape) -> Self {
RectangleBuilder {
shape: shape
}
}
}
}
在 ShapeBuilder
中,我们添加了一个 Shape
关联类型,指定每个 ShapeBuilder
将操作的 Shape
类型。 ShapeBuilder::new
现在使用此关联类型而不是类型参数来指定其操作数的类型。请注意,+ ?Sized
边界是必需的,因为否则会有一个隐式的 + Sized
边界,并且 Rust 抱怨 Shape
并不意味着 Sized
。解决此问题的另一种方法是将 : Sized
添加到 Shape
的定义中。
pub trait Shape: Sized {
type Builder: ShapeBuilder<Shape=Self>;
}