如何从struct name的字符串表示中立即转换struct

时间:2017-03-09 07:56:23

标签: go

是否允许您从字符串中实例化结构? (类似于Ruby中的ruby convert class name in string to actual class

我正在尝试将代码从单个文件分离到子目录中,但在运行 public static void main(String[] args) { Scanner sc = new Scanner(System.in); System.out.println("Enter amount: "); int num = sc.nextInt(); int r, SpacesAmount, re; for (r = 1; r <= num; r++) { for (SpacesAmount = num - r; SpacesAmount > 0; SpacesAmount--) System.out.print(" "); for (re = r; re >= 1; re--) System.out.print(re); for (re = 2; re <= r; re++) System.out.print(re); System.out.println(); } for (r = 1; r <= num; r++) { for (SpacesAmount = r; SpacesAmount >= 1; SpacesAmount--) System.out.print(" "); for (re = num - r; re >= 1; re--) System.out.print(re); for (re = 2; re <= num - r; re++) System.out.print(re); System.out.println(); } } 时获得undefined: PngConverter。它可能是一个加载顺序问题,但现在我正在尝试动态实例化结构。

convert_image.go

go build

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

2 个答案:

答案 0 :(得分:0)

不,您无法从字符串表示初始化结构。

Reference

您可以做的是通过ConvertImageToWords中的界面。

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

或者在Converter内将文件名转换为接口ConvertImageToWords

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
}

Reference

答案 1 :(得分:0)

动态评估

Go正在编译语言,这意味着没有动态评估,一切都在编译后完成。解释像Ruby,Python或Javascript这样的语言具有动态编程的eval(和类比)函数,这在编译语言时在概念上是不可能的。

接口作为一种惯用的抽象方式

如果你需要Go中的泛型类型 - 使用界面毫无疑问。您也非常接近正确的方法:您不需要从字符串中评估结构而不是它,您应该声明具有所有必需实现的Converter interface类型的对象的映射。

Compilable playground

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是包含package <name>作为第一行的go文件的目录。但是如果您使用不同的包(目录)分隔文件,则需要在需要在另一个包中使用它时将其导入。类似Java的类模块设计对于Go来说是不正确的。只需将所有转换器和接口保存在同一个包中。