繁体   English   中英

使这个 function 通用时如何满足特征界限?

[英]How to satisfy trait bounds when making this function generic?

我一直在使用 image-rs (0.23.12) 库来实现一些基本的图像分析功能,通过学习 Rust(我来自 Javascript/Python 背景)。 我通过 image-rs 为此目的提供的迭代器访问像素数据。 这是一个 function 的最小示例,它接受对图像子区域 ( image::SubImage ) 的引用并遍历其中的像素,与每个像素进行比较。

(游乐场链接

extern crate image;

use image::{GenericImageView, SubImage, ImageBuffer, Luma};

fn main() {
    let grey_image = ImageBuffer::new(300, 200);

    let subimg = grey_image.view(100, 100, 20, 20);
    
    find_dark_pixels(&subimg);
}

fn find_dark_pixels(img: &SubImage<&ImageBuffer<Luma<u8>, Vec<u8>>>)
{
    static WHITE: Luma<u8> = Luma([255]);
    let mut pixel_iter = img.pixels();
    if pixel_iter.any(|(_, _, pixel)| pixel != WHITE) {
        println!("Found dark pixels!");
    }
}

image::Luma是一个单色像素。)这个非通用版本的 function 编译和运行都很好。 但是,它确实需要参数是SubImage而不是别的。 不是很有用 - 它确实需要根据需要对整个图像或一个子集进行操作。 允许这样做的特征是GenericImageView ,并且 Image 和SubImage都实现了它。

我的第一次尝试是将 function 签名更改为:

fn find_dark_pixels<I: GenericImageView>(img: &I)

这从编译器中得出:

binary operation `!=` cannot be applied to type `<I as GenericImageView>::Pixel`
the trait `std::cmp::PartialEq` is not implemented for `<I as GenericImageView>::Pixel` rustc(E0369)

image-rs 中的像素类型确实实现PartialEq ,所以我告诉编译器:

fn find_dark_pixels<I: GenericImageView>(img: &I)
    where <I as GenericImageView>::Pixel: std::cmp::PartialEq
(the rest is unchanged)

然后它抱怨闭包中的“像素”和“白色”的类型不匹配:

mismatched types
expected associated type `<I as GenericImageView>::Pixel`
            found struct `Luma<u8>`
consider constraining the associated type `<I as GenericImageView>::Pixel` to `Luma<u8>`
for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html rustc(E0308)

我遵循(我相信?)编译器的建议并将 function 签名更改为:

fn find_dark_pixels<I: GenericImageView>(img: &I)
    where <I as GenericImageView>::Pixel: Luma<u8>
(the rest is unchanged)

编译器计数器:

expected trait, found struct `Luma`
not a trait rustc(E0404)

在这一点上,我尝试以各种方式注释“像素”和“白色”,但我认为自己被难住了。 你知道,我也知道,Luma 实现了比较pixel != WHITE ,但我不知道如何说服 rustc。

(如果有帮助,function 可以仅使用Luma<u8>, Vec<u8>类型的ImageBuffers - 我只需要使用单色图像。但它确实需要使用任何(不可变的)图像视图。 )

编译器关于“将关联类型<T as Trait>::Associated to Concrete约束”的建议意味着您需要直接在特征绑定中为关联类型请求具体类型。 这是通过Trait<Associated = Concrete>语法完成的 - 例如,要将I限制为生成字符串的迭代器,您可以编写I: Iterator<Item = String> find_dark_pixels的情况下,您会要求Pixel关联类型为Luma<u8> ,如下所示:

fn find_dark_pixels<I: GenericImageView<Pixel = Luma<u8>>>(img: &I) {

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM