这是Playground链接https://play.golang.org/p/qMKxqrOcc2。问题类似于Playground上的问题。
假设我有条件而且需要这样做:
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
我这样做是为了避免代码中的代码冗余,如果你问为什么。
问题类似于:How to return dynamic type struct in 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)
我知道这是愚蠢的,可能是不可能的,但是有这样做的方法:
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
。
这是代码中的冗余,它看起来很丑陋,但如果没有办法解决这个问题,那么我将完成这个冗余。
答案 0 :(得分:5)
您无法指定类型。您必须分配实例。您的代码实际上必须是以下内容。我在你想要改变的两行中添加了评论。
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这样的静态类型语言的目的。
答案 1 :(得分:2)
您收到错误是因为您尝试将类型分配给interface{}
实例。您需要分配一个实例。
如果你有;
var model interafce{}
if modelName == "a"{
model = models.A{}
}
else{
model = models.B{}
}
然后它会正常工作。
答案 2 :(得分:1)
这是您使用界面类型实现编辑的程序:
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
的参数,以显示接口类型的用法。