最近技术栈一直在更新,从Perl到Nodejs,再到golang,技术在不断的转换,技术思路迥异。从CVS、SVN到Git菜鸟,再到一般Git版本管理问题顺手能够解决,谈不上多大的成就感,但是独立解决问题后的愉悦永远值得回味。 通过学习这些新技术栈,我深刻体会到对技术人员来说,迎接变化,拥抱变化才是快速适应社会需求的根本技能。
最近一个项目需要对Go的结构体中interface{}字段进行扩展实例化,如果修改interface类型字段为目标结构体类型,问题能够解决了,但是却会再不需要引入扩展字段调用时填充空值,这时候interface{}类型就能够大显身手。
扩展Location interface{}字段,使其实例化
package tjsonimport ( "encoding/json" "fmt")type Server struct { ServerName string Serverip string Location interface{}}type Loc1 struct { City string Zip string}type Loc2 struct { City string PRovince string Zip string}type S struct { Servers []Server}// Tjson Test interface node which will bring different object infunc Tjson() { var s S s.Servers = append(s.Servers, Server{ServerName: "Shanghai_VPN", ServerIP: "127.0.0.1"}) loc1 := Loc1{ City: "Shanghai", Zip: "200001", } s.Servers[0].Location = loc1 s.Servers = append(s.Servers, Server{ServerName: "Beijing_VPN", ServerIP: "127.0.0.2"}) loc2 := &Loc2{ Province: "Hebei", City: "Xingtai", Zip: "005400", } s.Servers[1].Location = loc2 // General json Marshal // b, err := json.Marshal(s) // Beautiful json Marshal b, err := json.MarshalIndent(s, "", " ") if err != nil { fmt.Println("json err:", err) } fmt.Println(string(b))}测试代码
package tjsonimport "testing"func TestTjson(t *testing.T) { Tjson()}go test结果
我们可以从生成JSON结果看出,server结构中Location interface{}字段分别被两个不同结构体Loc1, Loc2扩展,并实例化。
代码下载: https://github.com/MarsBighead/garden/tree/master/test/tjson
Go语言接口(interface)特性决定了,任何类型(包括基础类型如bool、int、string等)都可以赋值给空接口(interface{}, 参考2)。
基于interface{}的特性,所以Location既可以被结构体Loc1实例化,又可以被结构体Loc2实例化。结构体S通过具名字段聚合,实现了结构体Server[]数组镶嵌,这样我们再实例化两个S元素时候可以分别对Server的Location interface{}字段实现不同结构体的实例话,并且能够得到很明显的对比效果。
interface{}的实例化实验证实了Go语言interface类型是Go语言的一大特性,恰如hash(哈希)至于Perl,字典之于Python。
新闻热点
疑难解答