繁体   English   中英

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

[英]How to define dynamic “type struct” in golang?

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

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

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

其中AB是一些模型:

type A struct{
    filed1 string
    field2 string
    //etc

}

模型B

type B struct{
    filed1 string
    field2 string
    //etc

}

AB中的字段具有一些相同的字段,但是大多数它们反映数据库表(文档),并且它们具有相同的类型(类型struct)。

当我在所有这些之前说:

var model interface{}

我收到错误消息:

type models.A is not an expression 

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

问题与此相似: 如何在Golang中返回动态类型struct?

这是代码的更新:

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)

我知道这很愚蠢,可能无法实现,但是有做到这一点的方法:

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

这是新的更新

我有两个模型Post和Product。 他们两个都有“照片”字段。

type Post struct{

    Photos []string
    //etc
}

type Product {

    Photos []string
    //
}

现在,我需要一个函数来说明这一点:

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
}

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

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

}

您可能唯一的区别是var model models.Post/var model models.Product 这是代码中的冗余,看起来很丑陋,但是如果没有办法解决,那么好了,我将用冗余完成此代码。

您无法分配类型。 您必须分配实例。 您的代码将必须有效地遵循以下条件。 我在要更改的两行中添加了注释。

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)
}

只是提一个建议,您可能不想使用通用interface{}类型,而最好使用AB实现的实际接口。 通用接口类型将使您更加头疼,并且实际上无法实现使用静态类型的语言(如Go)的目的。

由于尝试将类型分配给interface{}实例,因此出现错误。 您需要分配一个实例。

如果有的话;

var model interafce{}

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

那就可以了

这是您编辑的具有接口类型实现的程序:

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)
}

这里的移动部分是:

  • 类型的PhotoManager interface ,用于定义具有通用功能的接口
  • 的实现AddPhotosPostProduct提供的接口函数的实际实现
  • 使用pm PhotoManager作为AddPhotoToInterfaceImplementation参数来显示接口类型的用法。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM