如何在golang中定义动态"类型结构"?

pre*_*tch 1 go

这是Playground链接https://play.golang.org/p/qMKxqrOcc2.问题类似于Playground上的问题.

假设我有条件,需要这样做:

if modelName == "a"{
    model = models.A
} 
else{
    model = models.B
}
Run Code Online (Sandbox Code Playgroud)

在那里AB一些型号:

type A struct{
    filed1 string
    field2 string
    //etc

}
Run Code Online (Sandbox Code Playgroud)

和模型B

type B struct{
    filed1 string
    field2 string
    //etc

}
Run Code Online (Sandbox Code Playgroud)

字段在AB有一些相同的字段,但大多数它们反映数据库表(文档),它们是相同的类型(类型结构).

当我在所有的面前说:

var model interface{}
Run Code Online (Sandbox Code Playgroud)

我收到了错误:

type models.A is not an expression 
Run Code Online (Sandbox Code Playgroud)

如果你问为什么,我这样做是为了避免代码中的代码冗余.

问题类似于:如何在Golang中返回动态类型结构?

这是代码的更新:

b := c.mainHelper.GetModelBy("id", id, modelName).(map[string]interface{})
mapstructure.Decode(b, &model)

if modelName == "a"{
    model.Photos = []string{"ph1","ph2"}
}
if modelName == "b"{
    model.Docs = []string{"doc1","doc2"}
}

c.mainHelper.UpdateModel(product, id, modelName)
Run Code Online (Sandbox Code Playgroud)

我知道这是愚蠢的,可能是不可能的,但有这样做的方式:

var model models.modelName --> somehow to concat modelName to this models?
Run Code Online (Sandbox Code Playgroud)

这是最新的更新

我有两个型号Post和Product.他们俩都有照片领域.

type Post struct{

    Photos []string
    //etc
}

type Product {

    Photos []string
    //
}
Run Code Online (Sandbox Code Playgroud)

现在我需要一个能说出这个的功能:

func () RemovePhotos(id string, modelName string){

//if modelName=="post"
    //get model post with id

//if modelName=="product"
    //get model product with id

//set model.Photos = []string
//update model in db
}
Run Code Online (Sandbox Code Playgroud)

我可以理解我不能分配类型,但如何使用这一功能从不同类型中删除数据?据我所知,代码冗余将如下所示:

func () RemovePhotos(id string, modelName string) return bool{

    if modelName == "post"{

      var model models.Post
      modelWithdata := getModelWithId.(*model)
      modelWithdata.Photos = []string
      //update model in db here
    } 
    if modelName == "product"{
      var model models.Product
      modelWithdata := getModelWithId.(*model)
      modelWithdata.Photos = []string
      //update model in db here
    }

    //it does not matter what I return this is just redundancy example
    return true

}
Run Code Online (Sandbox Code Playgroud)

因为你只能区别是var模型models.Post/var model models.Product.这是代码中的冗余,它看起来很难看,但如果没有办法解决这个问题,那么我将完成这个冗余.

Wil*_*l C 6

您无法指定类型.您必须分配实例.您的代码实际上必须是以下内容.我在你要改变的两行中添加了评论.

package main

import "fmt"

type B struct {
    filed1 string
    field2 string
    //etc

}

type A struct {
    filed1 string
    field2 string
    //etc

}

func main() {
    var model interface{}
    modelName := "b"
    if modelName == "a" {
        model = A{} // note the {} here
    } else {
        model = B{} // same here
    }

    fmt.Println(model)
}
Run Code Online (Sandbox Code Playgroud)

只是一句忠告,你可能不想使用泛型interface{}类型,而是更好地使用既实现AB实现的实际接口.通用接口类型会让您更头疼,并且真正违背使用像Go这样的静态类型语言的目的.

  • 为了防止使用interface {},您可能需要查看[interfaces](http://jordanorelli.com/post/32665860244/how-to-use-interfaces-in-go)(sic) (3认同)