从struct的struct动态创建map [string]结构的常用函数

时间:2018-06-08 15:11:32

标签: go struct reflection

我有两个不同的结构,如下面提到的A abd B和两个过程函数。有没有办法通过这种方式我可以编写一个共同的函数来为map[string]struct生成struct。而且,有没有办法使用反射给定结构名称我可以创建相同的对象?

type A struct {
    name string
    // more fields
}


type B struct {
    name string
    // more fields  
}

func ProcessA(input []A) map[string]A {
    output := make(map[string]A)
    for _, v := range input {
         output[v.name] = v
    }
  return output
}


func ProcessB(input []B) map[string]B {
    output := make(map[string]B)
    for _, v := range input {
         output[v.name] = v
    }
  return output
}

2 个答案:

答案 0 :(得分:0)

Go中的惯用方法是使用界面。

type Named interface {
  Name() string
}

type letter struct {
  name string
}

func (l letter) Name() string {
  return l.name
}


type A struct {
    letter
    // more fields
}


type B struct {
    letter
    // more fields  
}

func ProcessNameds(input []Named) map[string]Named {
    output := make(map[string]Named, len(input))
    for _, v := range input {
         output[v.Name()] = v
    }
  return output
}

答案 1 :(得分:0)

好吧,看看这样的事情是否会有所帮助:

package main

import (
    "fmt"
    "strconv"
)

type A struct {
    name string
    // more fields
}

type B struct {
    name string
    // more fields
}

func Process(x interface{}) interface{} {
    ma := make(map[string]int)
    mb := make(map[string]string)

    if x == nil {
        return nil
    } else if a, ok := x.([]A); ok {
        fmt.Printf("Type A argument passed %s\n", x)
        ma[a[0].name] = 1
        ma[a[1].name] = 2
        return ma //you can return whatever type you want here
    } else if b, ok := x.([]B); ok {
        fmt.Printf("Type B argument passed %s\n", x)
        mb[b[0].name] = "a"
        mb[b[1].name] = "b"
        return mb //you can return whatever type you want here
    } else {
        panic(fmt.Sprintf("Unexpected type %T: %v", x, x))
    }
    return nil
}

func main() {
    a := make([]A, 5)
    for i := 0; i < len(a); i++ {
        a[i].name = strconv.Itoa(i) + "A"
    }
    b := make([]B, 7)
    for i := 0; i < len(b); i++ {
        b[i].name = strconv.Itoa(i) + "B"
    }

    fmt.Println(Process(a))
    fmt.Println(Process(b))
    //Uncomment line below to see the panic
    //fmt.Println(Process(8))

}

https://play.golang.org/p/irdCsbpvUv_t