1

我正在使用 Piston 和 Sprite 进行个人项目。示例代码调用此方法:

scene.draw(c.transform, g);

我正在尝试调用一种方法来绘制所有内容。我第一次尝试:

draw<G: Graphics>(&self, c: &Context, g: &mut G, scene: &mut Scene)

然后编译器告诉我我需要给它一个类型参数Scene所以我尝试了这个:

draw<G: Graphics, S>(&self, c: &Context, g: &mut G, scene: &mut Scene<S>)

然后编译器告诉我该类型需要实现特征ImageSize所以我尝试了这个:

draw<G: Graphics, S: ImageSize>(&self, c: &Context, g: &mut G, scene: &mut Scene<S>)

然后我得到了这个错误:

error[E0271]: type mismatch resolving `<G as graphics::Graphics>::Texture == S`
  --> src/game.rs:38:15
   |
38 |         scene.draw(c.transform, g);
   |               ^^^^ expected associated type, found type parameter
   |
   = note: expected type `<G as graphics::Graphics>::Texture`
          found type `S`

我不明白编译器在这里想说什么。的完整类型Scene是,sprite::Scene<piston_window::Texture<gfx_device_gl::Resources>> 但我不想在方法的签名中写下它。

那我有两个问题:

  1. 编译器想告诉我什么?
  2. 如何将场景传递给方法?
4

1 回答 1

1

的定义draw是:

impl<I: ImageSize> Scene<I> {
    fn draw<B: Graphics<Texture = I>>(&self, t: Matrix2d, b: &mut B)
}

换句话说,这大致对应于:

当使用实现Scene的类型进行参数化时,该函数将可用。用一个类型参数化,该类型必须实现特征,并且关联类型设置为. 该函数是一个对 a 的引用的方法,并接受另外两个参数:、 a和,一个对任何具体类型的可变引用。IImageSizedrawdrawBGraphicsTextureIdrawScenetMatrix2dbB

为了能够调用draw,您的函数需要具有相同的限制,但您不限制S与 相同Graphics::Texture。这样做允许代码编译:

extern crate sprite;
extern crate graphics;

use graphics::{Graphics, ImageSize, Context};
use sprite::Scene;

struct X;
impl X {
    fn draw<G>(&self, c: &Context, g: &mut G, scene: &mut Scene<G::Texture>)
    where
        G: Graphics,
    {
        scene.draw(c.transform, g);
    }
}

fn main() {}
于 2017-08-10T22:37:03.370 回答