gpt4 book ai didi

go - 将接口(interface)断言为其类型

转载 作者:IT王子 更新时间:2023-10-29 00:54:57 27 4
gpt4 key购买 nike

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

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 接口(interface)获取类型?

最佳答案

您的大型if ... else 结构可以通过使用type switch 来简化。像这样:

func getPixels(img image.Image) ([]uint8, error) {
switch i := img.(type) {
case *image.NRGBA:
return i.Pix, nil
case *image.Alpha:
return i.Pix, nil
case *image.Alpha16:
return i.Pix, nil
case *image.CMYK:
return i.Pix, nil
// ...
}
return nil, fmt.Errorf("unknown image type %T", img)
}

您仍然需要列出所有可能的类型,但这样更好。

由于所有图像实现都是具有名为 Pix 的字段的结构指针,您可以使用反射来获取该字段。此实现将处理 future 的图像实现而无需任何更改(如果它们也将是具有 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

关于go - 将接口(interface)断言为其类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52164276/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com