rust 函数返回类型有问题

6jygbczu  于 2022-11-12  发布在  其他
关注(0)|答案(1)|浏览(153)

我在创建一个从nannou返回以下Gradient类型(https://docs.rs/nannou/latest/nannou/color/gradient/struct.Gradient.html)的函数时遇到了麻烦。现在我意识到这对我来说通常是一个复杂泛型类型的问题。
我试着使用一个我见过的技巧,那就是在给定的类型上调用一个不存在的函数,让编译器抱怨。

8 |     gradient.asdfasdf();
  |              ^^^^^^^^ method not found in `nannou::color::Gradient<nannou::prelude::rgb::Rgb<nannou::color::encoding::Linear<Srgb>>>`

太好了!我的类型一定是nannou::color::Gradient<nannou::prelude::rgb::Rgb<nannou::color::encoding::Linear<Srgb>>>
然后我创建了一个函数,并将其作为返回类型:

pub fn get_gradient(color_1: Rgb, color_2: Rgb) -> nannou::color::Gradient<nannou::prelude::rgb::Rgb<nannou::color::encoding::Linear<Srgb>>> {
    let (r1, g1, b1) = color_1.into_components();
    let (r2, g2, b2) = color_2.into_components();

    Gradient::new(vec![lin_srgb(r1 as f32, g1 as f32, b1 as f32), lin_srgb(r2 as f32, g2 as f32, b2 as f32)]);
}

但随后编译器给出了一个新的错误:

error[E0277]: the trait bound `nannou::prelude::rgb::Rgb: RgbSpace` is not satisfied
  --> examples/utils/color.rs:3:52
   |
3  | ...color_2: Rgb) -> nannou::color::Gradient<nannou::prelude::rgb::Rgb<nannou::color::encoding::Linear<Srgb>>> {
   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `RgbSpace` is not implemented for `nannou::prelude::rgb::Rgb`
   |
   = help: the following other types implement trait `RgbSpace`:
             (P, W)
             nannou::color::encoding::Srgb
   = note: required because of the requirements on the impl of `RgbStandard` for `nannou::color::encoding::Linear<nannou::prelude::rgb::Rgb>`
note: required by a bound in `nannou::prelude::rgb::Rgb`
  --> /Users/brittcagnina/.cargo/registry/src/github.com-1ecc6299db9ec823/palette-0.5.0/src/rgb/rgb.rs:46:19
   |
46 | pub struct Rgb<S: RgbStandard = Srgb, T: Component = f32> {
   |                   ^^^^^^^^^^^ required by this bound in `nannou::prelude::rgb::Rgb`

我不确定如何处理或解释此错误。不仅是此特定类型,而且是一般类型。我在此库中使用泛型的几个其他类型中遇到了问题。解决此问题所需的一般策略或原则是什么?
谢谢你!

hfyxw5xn

hfyxw5xn1#

原来nannou板条箱中的命名相当混乱。
有多种Rgb类型:

  • nannou_core::color::Rgb,重新导出为:
  • nannou::color::Rgb
  • nannou::prelude::Rgb
  • palette::rgb::Rgb,重新导出为:
  • nannou::color::rgb::Rgb
  • nannou::prelude::rgb::Rgb

此外,存在多个Srgb类型:

  • palette::rgb::Srgb,重新导出为:
  • nannou::color::rgb::Srgb
  • nannou::prelude::rgb::Srgb
  • palette::encoding::srgb::Srgb,重新导出为:
  • nannou::color::encoding::Srgb

请注意,特别是在Rgb的情况下,即使是文档也会混淆,并倾向于链接到错误的Rgb类型。
无论哪种方式,您所犯的实际错误都是选择了错误的Srgb类型:

use nannou::{color::Gradient, prelude::*};

pub fn get_gradient(
    color_1: Rgb,
    color_2: Rgb,
) -> nannou::color::Gradient<
    nannou::prelude::rgb::Rgb<nannou::color::encoding::Linear<nannou::color::encoding::Srgb>>,
> {
    let (r1, g1, b1) = color_1.into_components();
    let (r2, g2, b2) = color_2.into_components();

    Gradient::new(vec![
        lin_srgb(r1 as f32, g1 as f32, b1 as f32),
        lin_srgb(r2 as f32, g2 as f32, b2 as f32),
    ])
}

或者,您甚至不需要完整的形式,因为Rgb<Linear<Srgb>, f32>只是lin_srgb的实际返回类型的长形式,即LinSrgb<f32>

use nannou::{color::Gradient, prelude::*};

pub fn get_gradient(color_1: Rgb, color_2: Rgb) -> Gradient<LinSrgb<f32>> {
    let (r1, g1, b1) = color_1.into_components();
    let (r2, g2, b2) = color_2.into_components();

    Gradient::new(vec![
        lin_srgb(r1 as f32, g1 as f32, b1 as f32),
        lin_srgb(r2 as f32, g2 as f32, b2 as f32),
    ])
}

相关问题