如何从结构名称的字符串表示形式实现struct



是否可以让您从字符串实例化结构?(类似于Ruby在Ruby中的Ruby将字符串名称转换为实际类)

我正在尝试将代码与单个文件分开为子目录,但是在运行go build时会获得undefined: PngConverter。这可能是一个负载订单问题,但是现在我试图动态实例化结构。

convert_image.go

var converters = map[string]string{
  "png": "PngConverter",
  "jpg": "JpegConverter",
  "jpeg": "JpegConverter",
}
type Converter interface {
  convert(*bytes.Buffer) string
}
func selectConverter(converterName string) {
  // dynamically initialize the converter with reflect?
}
func ConvertImageToWords(filename string, image *bytes.Buffer) string {
  ext = Ext(filename)
  if converterName, y := converters[ext]; y {
    converter = selectConverter(converterName)
    id = converter.convert(image)
  }
  return nil
}

converters/png_converter.go

type PngConverter struct {}
func (converter PngConverter) convert(in *bytes.Buffer) string {
  // ...
}

converters/jpeg_converter.go

type JpegConverter struct {}
func (converter JpegConverter) convert(in *bytes.Buffer) string {
  // ...
}

动态评估

go是编译语言,这意味着没有动态评估,一切都是在编译后完成的。诸如Ruby,Python或JavaScript之类的语言具有eval(和模拟)函数的动态编程功能,从概念上讲,这对于编译语言是不可能的。

接口作为抽象的惯用方式

如果您需要GO中的通用类型 - 毫无疑问使用接口。另外,您非常接近正确的方法:您不需要从字符串中评估结构而不是它,您应该声明具有所有必需实现的Converter interface类型对象的地图。

可编译的操场:

var converters map[string]Converter
type Converter interface {
    convert(*bytes.Buffer) string
}
type PngConverter struct{}
type JpgConverter struct{}
func (p *PngConverter) convert(b *bytes.Buffer) (repr string) { return }
func (p *JpgConverter) convert(b *bytes.Buffer) (repr string) { return }
func ConvertImageToWords(
        filename string,
        image *bytes.Buffer,
        converters map[string]Converter) (repr string) {
    ext := Ext(filename)
    if converter, y := converters[ext]; y {
        repr = converter.convert(image)
    }
    return
}

导入和软件包

您尚未被问到,但这是错误的设计:

是的,它们在单独的目录中...

软件包是一个命名空间,您可以拥有多个文件,并且您无需将它们导入另一个文件。软件包是一个目录,其中包含package <name>作为第一行的GO文件。但是,如果您使用不同的软件包(目录)将文件分开,则需要将其导入,如果需要在另一个软件包中使用它。类似Java的类模块设计对GO不正确。只需将所有转换器和界面保存在同一软件包中。

不,您不能从字符串表示。

初始化struct。

参考

您可以做的是通过ConvertImageToWords中的接口。

func ConvertImageToWords(conv Converter, image *bytes.Buffer) string

或将文件名转换为ConvertImageToWords中的接口Converter

func GetConverter(ext string) Converter {
  switch ext {
    case "png":
      return PngConverter{}
    case "jpg":
   ...
}
func ConvertImageToWords(filename string, image *bytes.Buffer) string {
  ext = Ext(filename)
  conv := GetConverter(ext)
  id := conv.convert(image)
  ...
}

也最好导出接口方法:

type Converter interface {
  Convert(*bytes.Buffer) string
}

参考

最新更新