go: 接口的类型断言

huangapple go评论91阅读模式
英文:

go: type assert of interface

问题

我有一个关于创建结构体动态模型的问题。我的意思是,根据传入的数据结构,我想要断言、转换或者仅仅改变结构体的类型。

如果sourceName变量是type_x,那么deserializedData的类型应该是type_x;如果是type_y,那么就是type_y。如何动态地设置变量deserializedData

我代码中的这部分如下:

....
var cacheData []byte
var deserializedData models.NoaggModel

cache_err := cache.Get(string(string(sourceName) + "_" + string(t.Date)), &cacheData)
if cache_err != nil {
    fmt.Println("cache_error: ", cache_err)
    panic("the cache is empty")
}

err2 := json.Unmarshal([]byte(cacheData), &deserializedData)
if err2 == nil {
    fmt.Println("deserialized data: " + string(sourceName), deserializedData)
}

for _, chart := range charts {
    w.Name = chart.Name

    if err2 == nil {
        w.Data = countDataByName(sourceName, deserializedData, t.Request.Filters, string(chart.Name))
    }
    out <- w
}
....

如何修改它,以避免严格设置models.NoaggModel类型?

英文:

I have a problem with making dynamic model of a struct. I mean that I want to assert or cast, or just change the type of struct according to the incoming data strut.

if sourceName variable would be type_x , than the type of deserializedData should be type_x, if type_y, than type_y. How to set the variable deserializedData dynamicly for this ?

I have this part in my code:

    .... 
     
     

  var cacheData []byte
    var deserializedData models.NoaggModel
  
    cache_err := cache.Get(string(string(sourceName) + &quot;_&quot; + string(t.Date)), &amp;cacheData);
    		if cache_err != nil {
    			fmt.Println(&quot;cache_error: &quot;, cache_err)
    			panic(&quot;the cache is empty&quot;)
    		}
    
    		err2 := json.Unmarshal([]byte(cacheData), &amp;deserializedData)
    		if err2 == nil {
    			fmt.Println(&quot;deserialized data: &quot; + string(sourceName), deserializedData)
    		}
    
    		for _, chart := range charts {
    			w.Name = chart.Name
    
    		if err2 == nil {
    			
    			w.Data = countDataByName(sourceName, deserializedData, t.Request.Filters, string(chart.Name))
    		}
            out &lt;- w
		}
....

How to modify it, to avoid setting models.Noagg Model type in a strict way?

答案1

得分: 4

在运行时动态创建类型的实例可以使用 reflect 包来实现。你可以使用一个映射(map)来存储应该能够创建的不同类型:

示例代码:

package main

import (
	"fmt"
	"reflect"
)

type Foo struct {
	Foo string
}

type Bar struct {
	Bar int
}

func main() {
	var sourceTypes = map[string]reflect.Type{
		"foo": reflect.TypeOf(Foo{}),
		"bar": reflect.TypeOf(Bar{}),
	}

	sourceName := "foo"
	var deserializedData interface{}

	deserializedData = reflect.New(sourceTypes[sourceName]).Interface()
	fmt.Printf("%#v", deserializedData)
}

输出结果:

&main.Foo{Foo:""}

Playground: http://play.golang.org/p/qeDA4cu5et

英文:

Creating an instance of a type dynamically during runtime can be done using the reflect package. You can use a map to store the different types that you should be able to create:

Example:

package main

import (
	&quot;fmt&quot;
	&quot;reflect&quot;
)

type Foo struct {
	Foo string
}

type Bar struct {
	Bar int
}

func main() {
	var sourceTypes = map[string]reflect.Type{
		&quot;foo&quot;: reflect.TypeOf(Foo{}),
		&quot;bar&quot;: reflect.TypeOf(Bar{}),
	}

	sourceName := &quot;foo&quot;
	var deserializedData interface{}

	deserializedData = reflect.New(sourceTypes[sourceName]).Interface()
	fmt.Printf(&quot;%#v&quot;, deserializedData)
}

Output:

> &main.Foo{Foo:""}

Playground: http://play.golang.org/p/qeDA4cu5et

huangapple
  • 本文由 发表于 2016年2月15日 20:25:16
  • 转载请务必保留本文链接:https://go.coder-hub.com/35409342.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定