if ...else通过使用如下所示的类型开关,可以简化大型结构:
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,因此您可以使用反射来获取该字段。此实现将处理将来的图像实现,而无需进行任何更改(如果它们也将是具有
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



