Making generic function...

blov · · 309 次点击    
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
<p>I need to make a function that takes some sort of generic parameter. I know there aren&#39;t explicit generics in Go but I&#39;m wondering what the best way to do this is.</p> <p>marshalDictValuesToJSON() should be able to take a map and turn all of the values into JSON ([]byte).</p> <pre><code> type user struct { First string Last string } func main() { userDict := make(map[int]user) userDict[1] = user{&#34;Davy&#34;, &#34;Jones&#34;} userDict[2] = user{&#34;Jeff&#34;, &#34;Johnson&#34;} a := marshalDictValuesToJSON(userDict) } func marshalDictValuesToJSON(dict map[int]interface{}) map[int][]byte { dictJSON := make(map[int][]byte) for k, v := range dict { bytes, err := json.Marshal(v) if err != nil { continue } dictJSON[k] = bytes } return dictJSON } </code></pre> <p>I get the error:</p> <blockquote> <p>cannot use userDict (type map[int]user) as type map[int]interface {} in argument to marshalDictValuesToJSON</p> </blockquote> <p>The values in the map need to be &#34;generic&#34; somehow.</p> <p>Is there a way I can do this in Go? Or should I just copy &amp; paste with all the different map types I have?</p> <hr/>**评论:**<br/><br/>r-_3: <pre><p>Looks like a typical Y, X problem. Anyway. You need to manually convert map[int]user to map[int]interface{} with a for loop.</p></pre>wemgl: <pre><p>A more idiomatic way to do this in Go would be to create an interface that has a method that returns a []byte. You then have your user type, or whatever type you want marshaled to JSON, satisfy that interface. </p> <p>Finally, you use the interface name for the values in the map and change the argument of marshalDictValuesToJSON to handle the map to your interface and your code should work for any object that satisfies the interface. So, the result should be the following:</p> <p>` package main</p> <pre><code>import ( “encoding/json” “fmt” ) type JSONmarshaler interface { marshalJSON() ([]byte, error) } type user struct { First string Last string } func (u *user) marshalJSON() ([]byte, error) { json, err := json.Marshal(u) return json, err } func main() { userDict := make(map[int]JSONmarshaler) userDict[1] = &amp;user{“Davy”, “Jones”} userDict[2] = &amp;user{“Jeff”, “Johnson”} a := marshalDictValuesToJSON(userDict) fmt.Println(a) } func marshalDictValuesToJSON(dict map[int]JSONmarshaler) map[int][]byte { dictJSON := make(map[int][]byte) for k, v := range dict { bytes, err := v.marshalJSON() if err != nil { continue } dictJSON[k] = bytes } return dictJSON }` </code></pre></pre>wemgl: <pre><p>Sorry for the crap formatting I wrote this on mobile. </p></pre>Sythe2o0: <pre><p>You can convert the type in a range to a map of interfaces:</p> <p><a href="https://play.golang.org/p/1jeSeKbBS-" rel="nofollow">https://play.golang.org/p/1jeSeKbBS-</a></p></pre>shovelpost: <pre><p>You can easily wrap your <code>map[int]user</code> to <code>map[int]interface{}</code> : <a href="https://play.golang.org/p/jG4nkGTU9H" rel="nofollow">https://play.golang.org/p/jG4nkGTU9H</a></p> <p>But if all your map types need <code>marshalDictValuesToJSON</code> why not make them new types, attach methods to them and define an interface with their common behavior?</p></pre>

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

309 次点击  
加入收藏 微博
0 回复
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传