dongtuo4723 2016-04-07 18:31
浏览 493
已采纳

如何在golang中定义动态的“类型结构”?

Here is Playground link https://play.golang.org/p/qMKxqrOcc2. Problem is similar to one that is on Playground.

Let's say I have a condition and need to do this:

if modelName == "a"{
    model = models.A
} 
else{
    model = models.B
}

where A and B are some models:

type A struct{
    filed1 string
    field2 string
    //etc

}

and model B is

type B struct{
    filed1 string
    field2 string
    //etc

}

Fields in A and B has some same fields but mostly they reflect database table (document) and they are of same type (type struct).

When I say in front of all that:

var model interface{}

I got error:

type models.A is not an expression 

I am doing this to avoid code redundancy in code if you are asking why.

Question is similar to this: How to return dynamic type struct in Golang?

Here is update for code:

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)

I know this is stupid and probably is impossible to do but is there and way to do this:

var model models.modelName --> somehow to concat modelName to this models?

HERE IS NEW UPDATE

I have two models Post and Product. Both of them has Photos field.

type Post struct{

    Photos []string
    //etc
}

type Product {

    Photos []string
    //
}

Now I need one function that will say this:

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
}

I can understand that I can not assign type but how to use this one function to remove data from differnt types? As far as I can see code redundancy will look like this:

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

}

As you can only difference is var model models.Post/var model models.Product. This is redundancy in code and it looks ugly but if there is no way around this then ok, i will have this one completed with redundancy.

  • 写回答

3条回答 默认 最新

  • dongpi9164 2016-04-11 11:54
    关注

    This is your program from the edit with a interface type implementation:

    package main
    
    import (
        "log"
    )
    
    //// Interfaces ////
    type PhotoManager interface {
        AddPhotos(id string) (bool, error)
    }
    
    //// Post ////
    type Post struct {
        Photos []string
    }
    
    func (p *Post) AddPhotos(id string) (bool, error) {
        p.Photos = append(p.Photos, id)
        return true, nil
    }
    
    //// Product ////
    type Product struct {
        Photos []string
        Docs   []string
    }
    
    func (p *Product) AddPhotos(id string) (bool, error) {
        p.Photos = append(p.Photos, id)
        return true, nil
    }
    
    // Useless function to demonstrate interface usage //
    func AddPhotoToInterfaceImplementation(id string, pm PhotoManager) {
        pm.AddPhotos(id)
    }
    
    //// Main ////
    func main() {
        post := Post{}
        product := Product{}
        post.AddPhotos("123")
        product.AddPhotos("321")
        AddPhotoToInterfaceImplementation("456", &post)
        AddPhotoToInterfaceImplementation("654", &product)
        log.Println(post)
        log.Println(product)
    }
    

    The moving parts here are:

    • the type PhotoManager interface that is used to define an interface with generic functions
    • the implementations of AddPhotos on Post and Product to provide the actual implementations of the interface functions
    • the usage of pm PhotoManager as parameter to AddPhotoToInterfaceImplementation to show the usage of the interface type.
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

悬赏问题

  • ¥15 2020长安杯与连接网探
  • ¥15 关于#matlab#的问题:在模糊控制器中选出线路信息,在simulink中根据线路信息生成速度时间目标曲线(初速度为20m/s,15秒后减为0的速度时间图像)我想问线路信息是什么
  • ¥15 banner广告展示设置多少时间不怎么会消耗用户价值
  • ¥16 mybatis的代理对象无法通过@Autowired装填
  • ¥15 可见光定位matlab仿真
  • ¥15 arduino 四自由度机械臂
  • ¥15 wordpress 产品图片 GIF 没法显示
  • ¥15 求三国群英传pl国战时间的修改方法
  • ¥15 matlab代码代写,需写出详细代码,代价私
  • ¥15 ROS系统搭建请教(跨境电商用途)