功能返回类型出现故障



我在创建返回以下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`

我不确定如何继续,甚至不确定如何解释这个错误。不仅是这种特殊类型,而且是一般情况。在这个库中,我遇到了其他几种使用泛型的类型的问题。解决这个问题需要什么样的总体策略或原则?

谢谢!

原来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),
])
}

最新更新