[英]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
}
其中A
和B
是一些模型:
type A struct{
filed1 string
field2 string
//etc
}
模型B
是
type B struct{
filed1 string
field2 string
//etc
}
A
和B
中的字段具有一些相同的字段,但是大多数它们反映数据库表(文档),并且它们具有相同的类型(类型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{}
类型,而最好使用A
和B
实现的实际接口。 通用接口类型将使您更加头疼,并且实际上无法实现使用静态类型的语言(如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
,用于定义具有通用功能的接口 AddPhotos
上Post
和Product
提供的接口函数的实际实现 pm PhotoManager
作为AddPhotoToInterfaceImplementation
参数来显示接口类型的用法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.