猿问

将接口断言为其类型

在一般情况下,我无法优雅地将图像的像素作为数组获取。


f, err := os.Open(imgPath)

check(err)

defer f.Close()

img, _, err := image.Decode(bufio.NewReader(f))

check(err)

pixels, err := getPixels(img)

check(err)

// Logic with pixels.

现在函数 getPixels 看起来像这样:


func getPixels(img image.Image) ([]uint8, error) {

    if i, ok := img.(*image.NRGBA); ok {

        return i.Pix, nil

    } else if i, ok := img.(*image.Alpha); ok {

        return i.Pix, nil

    } else if i, ok := img.(*image.Alpha16); ok {

        return i.Pix, nil

    } else if i, ok := img.(*image.CMYK); ok {

        return i.Pix, nil

    } else if i, ok := img.(*image.Gray); ok {

        return i.Pix, nil

    } else if i, ok := img.(*image.Gray16); ok {

        return i.Pix, nil

    } else if i, ok := img.(*image.NRGBA64); ok {

        return i.Pix, nil

    } else if i, ok := img.(*image.Paletted); ok {

        return i.Pix, nil

    } else if i, ok := img.(*image.RGBA); ok {

        return i.Pix, nil

    } else if i, ok := img.(*image.RGBA64); ok {

        return i.Pix, nil

    }

    return nil, fmt.Errorf("unknown image type %T", img)

}

但我认为这很丑陋。Golang 知道图像的类型,我更喜欢这样的东西:


func getPixels(img image.Image) ([]uint8, error) {

    if i, ok := img.(eval(fmt.Sprintf("%T", img))); ok {

        return i.Pix, nil

    }

    return nil, fmt.Errorf("unknown image type %T", img)

}

我也不能断言reflect.TypeOf(img)。也许有办法从reflect.Type界面获取类型?


四季花海
浏览 124回答 1
1回答

长风秋雁

你的大if ... else结构可以通过使用这样的类型开关来简化:您仍然需要列出所有可能的类型,但这样更好。由于所有图像实现都是具有名为 的字段的结构指针Pix,因此您可以使用反射来获取该字段。此实现将处理未来的图像实现而无需任何更改(如果它们也将是具有Pix字段的结构)。这就是它的样子:func getPix(img image.Image) ([]uint8, error) {    v := reflect.ValueOf(img)    if v.Kind() == reflect.Ptr {        v = v.Elem()    }    if v.Kind() == reflect.Struct {        pv := v.FieldByName("Pix")        if pv.IsValid() {            if pix, ok := pv.Interface().([]uint8); ok {                return pix, nil            }        }    }    return nil, fmt.Errorf("unknown image type %T", img)}测试它:fmt.Println(getPix(&image.NRGBA{}))fmt.Println(getPix(&image.RGBA{}))type unknownImage struct{ image.Image }fmt.Println(getPix(unknownImage{}))输出(在Go Playground上尝试):[] <nil>[] <nil>[] unknown image type main.unknownImage
随时随地看视频慕课网APP

相关分类

Go
我要回答