将接口声明为其类型 [英] Assert interface to its type
问题描述
在一般情况下,我无法正常获取图像的像素作为数组.
I can't gracefully get pixels of an image as array in general case.
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看起来像这样:
Now function getPixels looks like this:
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知道图像的类型,我更喜欢这样的东西:
But I think this is ugly. Golang knows type of image and I would prefer something like this:
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
界面获取类型?
I also can't assert to reflect.TypeOf(img)
. Maybe there is a way to get type from reflect.Type
interface?
推荐答案
使用
您仍然必须列出所有可能的类型,但这更好. Where you still have to list all possible types, but it's nicer. 由于所有图像实现都是具有名为 Since all image implementations are struct pointers having a field named 它是这样的: 测试: 输出(在转到游乐场上尝试): 这篇关于将接口声明为其类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!Pix
的字段的结构指针,因此您可以使用反射来获取该字段.此实现将处理将来的图像实现,而无需进行任何更改(如果它们也将是具有Pix
字段的结构).Pix
, you may use reflection to get that field. This implementation will handle future image implementations without any change (if they will also be structs with a Pix
field).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{}))
[] <nil>
[] <nil>
[] unknown image type main.unknownImage