为了账号安全,请及时绑定邮箱和手机立即绑定

将接口断言为其类型

将接口断言为其类型

Go
四季花海 2023-03-29 16:13:38
在一般情况下,我无法优雅地将图像的像素作为数组获取。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界面获取类型?
查看完整描述

1 回答

?
长风秋雁

TA贡献1757条经验 获得超7个赞

你的大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


查看完整回答
反对 回复 2023-03-29
  • 1 回答
  • 0 关注
  • 102 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信