宁波高端建站,做网站算新媒体运营吗,网站建设 柳州,商城类网站建设步骤文章目录 struct结构体类的表示与封装类的继承多态的基本要素与实现interface空接口反射变量的内置pairreflect包解析Struct TagStruct Tag在json中的应用 struct结构体 
在Go语言中#xff0c;可以使用type 关键字来创建自定义类型#xff0c;这对于提高代码的可读性和可维护… 文章目录 struct结构体类的表示与封装类的继承多态的基本要素与实现interface空接口反射变量的内置pairreflect包解析Struct TagStruct Tag在json中的应用   struct结构体 
在Go语言中可以使用type 关键字来创建自定义类型这对于提高代码的可读性和可维护性非常有用。如type myint intmyint 是一个基于内置类型 int 创建的自定义类型。你可以在代码中使用 myint 类型并对其进行操作而它实际上是基础的 int 类型。 
struct的定义如下 
package mainimport fmt// Book 定义一个结构体
type Book struct {title stringauth  string
}func main() {var book1 Bookbook1.title  Golangbook1.auth  zhangsanfmt.Println(book1)
}
// {Golang zhangsan}需要注意的是 Go 语言中函数参数默认是值传递的。如果将book1对象传入函数中时仅仅只是传进去一个副本在函数中对book1的任何修改都是无效的。如果想在函数中修改原始变量可以传递指向结构体的指针。如以下代码所示。 
package mainimport fmt// Book 定义一个结构体
type Book struct {title stringauth  string
}func changeBook(book *Book) {book.auth  777
}func main() {var book1 Bookbook1.title  Golangbook1.auth  zhangsanchangeBook(book1)fmt.Println(book1)
}
// {Golang 777}类的表示与封装 
Go语言通常称为Golang不使用传统的类class和继承inheritance的概念而是通过结构体struct来实现面向对象编程的特性。 go中没有public和private的关键字如果类名大写则其他包也能够访问如果标识符以小写字母开头则它是未导出的只能在同一个包内访问。导出的标识符大写字母开头不仅仅限于结构体名字还包括结构体中的字段名、函数名等。这种命名规范有助于代码的可维护性和封装性。 package mainimport fmttype Hero struct {Name  stringAd    intLevel int
}func (this Hero) Show() {fmt.Println(name , this.Name)fmt.Println(Ad , this.Ad)fmt.Println(Level , this.Level)
}func (this Hero) GetName() string {return this.Name
}func (this Hero) SetName(newName string) {this.Name  newName
}func main() {hero : Hero{Name: zhangsan, Ad: 100, Level: 1}hero.Show()hero.SetName(lisi)nowName : hero.GetName()fmt.Println(nowName , nowName)
}
/*输出结果
name  zhangsan
Ad  100
Level  1
nowName  zhangsan
*/可以看出setName并没有把名字改为lisi。因为setName方法中使用的是值接收者receiver这意味着在该方法内部对Hero实例的修改不会影响到实际的hero变量。要使setName方法正确地修改Hero实例需要将其改为指针接收者。如以下代码所示。 
package mainimport fmttype Hero struct {Name  stringAd    intLevel int
}func (this *Hero) Show() {fmt.Println(name , this.Name)fmt.Println(Ad , this.Ad)fmt.Println(Level , this.Level)
}func (this *Hero) GetName() string {return this.Name
}func (this *Hero) SetName(newName string) {this.Name  newName
}func main() {hero : Hero{Name: zhangsan, Ad: 100, Level: 1}hero.Show()hero.SetName(lisi)nowName : hero.GetName()fmt.Println(nowName , nowName)
}
/*输出结果
name  zhangsan
Ad  100
Level  1
nowName  lisi
*/类的继承 
现在有如下的一个Human类 
package mainimport fmttype Human struct {name stringsex  string
}func (this *Human) Eat() {fmt.Println(Human.Eat()...)
}func (this *Human) Walk() {fmt.Println(Human.Walk()...)
}func main() {h : Human{name: zhangsan, sex: male}h.Eat()h.Walk()
}现在有一个SuperMan类需要继承Human类还有自己的level字段并重写其中的Eat方法还要能够写子类的新方法。代码如下 
type SuperMan struct {Human // SuperMan继承了Human类的方法level int
}// 重写父类的Eat()方法
func (this *SuperMan) Eat() {fmt.Println(SuperMan.Eat()...)
}// 添加子类新方法
func (this *SuperMan) Fly() {fmt.Println(SuperMan.Fly()...)
}在继承完成后main函数中定义子类的对象有两种方法。 第一种一气通贯式 
s : SuperMan{Human{lisi, female}, 5}第二种守旧派 
var s SuperMan
s.name  lisi
s.sex  female
s.level  5完整代码如下都能成功运行。 
package mainimport fmttype Human struct {name stringsex  string
}func (this *Human) Eat() {fmt.Println(Human.Eat()...)
}func (this *Human) Walk() {fmt.Println(Human.Walk()...)
}// type SuperMan struct {Human // SuperMan继承了Human类的方法level int
}// 重写父类的Eat()方法
func (this *SuperMan) Eat() {fmt.Println(SuperMan.Eat()...)
}// 添加子类新方法
func (this *SuperMan) Fly() {fmt.Println(SuperMan.Fly()...)
}func (this *SuperMan) Show() {fmt.Println(name , this.name)fmt.Println(sex , this.sex)fmt.Println(level , this.level)
}func main() {h : Human{name: zhangsan, sex: male}h.Eat()h.Walk()fmt.Println()//方法一定义子类新对象//s : SuperMan{Human{lisi, female}, 5}//方法二var s SuperMans.name  lisis.sex  females.level  5s.Walk() //父类方法s.Eat()s.Fly()s.Show()
}
/*运行结果
Human.Eat()...
Human.Walk()...Human.Walk()...
SuperMan.Eat()...
SuperMan.Fly()...
name  lisi
sex  female
level  5
*/多态的基本要素与实现 
Go语言中用继承是无法实现多态的需要用接口(interface)实现它的本质是一个指针。 基本要素 
有一个父类有接口有子类实现了父类的全部接口方法父类类型的变量指针指向引用子类的具体数据变量 
以下代码展示了一个使用接口的例子定义了一个 AnimalIF 接口和两个实现该接口的类型 Cat 和 Dog。然后通过 showAnimal 函数展示了如何使用接口进行多态性调用。 
package mainimport fmttype AnimalIF interface {Sleep()GetColor() stringGetType() string
}type Cat struct {color string
}func (this *Cat) Sleep() {fmt.Println(cat is sleeping)
}func (this *Cat) GetColor() string {return this.color
}func (this *Cat) GetType() string {return cat
}//type Dog struct {color string
}func (this *Dog) Sleep() {fmt.Println(dog is sleeping)
}func (this *Dog) GetColor() string {return this.color
}func (this *Dog) GetType() string {return Dog
}func showAnimal(animal AnimalIF) {animal.Sleep()fmt.Println(color , animal.GetColor())fmt.Println(kind , animal.GetType())
}func main() {//var animal AnimalIF //接口的数据类型父类指针//animal  Cat{Green}//animal.Sleep()////animal  Dog{yellow}//animal.Sleep()cat : Cat{green}dog : Dog{yellow}showAnimal(cat)showAnimal(dog)
}在 main 函数中我们创建了 Cat 和 Dog 的实例并通过showAnimal 函数调用展示它们的信息。这里利用了接口的多态性通过相同的接口来处理不同的类型。这种设计使得代码更加灵活可以方便地扩展和添加新的类型。 
interface空接口 
在Go语言中空接口empty interface是一种特殊的接口它不包含任何方法签名。由于不包含任何方法空接口可以表示任意类型。在Go中空接口的声明形式是interface{}。 空接口的特点是它可以保存任意类型的值因为任何类型都至少实现了零个方法因此都满足空接口的要求。 
package mainimport fmtfunc myFunc(arg interface{}) {fmt.Println(myFunc is called...)fmt.Println(arg)
}type Books struct {auth string
}func main() {book : Books{zhangsan}myFunc(book)myFunc(100)myFunc(haha)myFunc(3.14)
}
/*输出结果
myFunc is called...
{zhangsan}
myFunc is called...
100
myFunc is called...
haha
myFunc is called...
3.14
*/在这个例子中myFunc 函数接受一个空接口类型的参数因此它可以接受任何类型的值。然后创建了一个 Books 结构体的实例 book并将其作为参数传递给 myFunc 函数。 
但是interface{}如何区分此时引用的底层数据类型是什么主要是通过断言机制来实现的。 
func myFunc(arg interface{}) {fmt.Println(myFunc is called...)fmt.Println(arg)value, ok : arg.(string)if !ok {fmt.Println(arg is not string)} else {fmt.Println(value , value)fmt.Println(arg is string)}
}这种方式在运行时进行了类型检查以确保转换的安全性。如果 arg 的实际类型不是 string那么 ok 将为 false并输出相应的提示信息。 
反射 
变量的内置pair 
在Go中如果定义了一个变量那么它内部实际构造由两部分组成变量类型type和值value。type可以划分成两类static type和concrete type。 
static type指常见的数据类型如int、string…concrete type指interface所指向的具体数据类型是系统看得见的类型 
变量类型type和值value组成了pair反射主要是通过变量找到当前变量的具体类型或值。具体结构如下图所示。  
package mainimport fmtfunc main() {var a string// pairstatic_type:string,value:acelda  aceld//pairtype:string,value:aceldvar alltype interface{}alltype  astr, _ : alltype.(string)fmt.Println(str)
}这段代码中alltype.(string) 尝试将 alltype转为字符串类型并返回两个值一个是转换后的值 str另一个是一个布尔值 ok 表示转换是否成功。在这里使用了 _ 来忽略不需要的第二个返回值。 如果转换成功ok 为 true则会打印出字符串的值。如果转换失败ok 为 false则会输出相应的提示信息。这种模式在处理接口类型时常用于确保类型安全。 
reflect包 
reflect主要包含了两个关键的接口ValueOf实现输入任意数据类型返回数据的值TypeOf实现输入任意数据类型动态获取这个数据类型是static type还是concrete type。  可以用以下代码来判断 
package mainimport (fmtreflect
)func reflectNum(arg interface{}) {fmt.Println(type:, reflect.TypeOf(arg))fmt.Println(value:, reflect.ValueOf(arg))
}func main() {var num float64  3.14159reflectNum(num)
}
/*输出结果
type: float64
value: 3.14159
*/下面的代码演示了如何使用反射reflection获取结构体实例的字段和方法信息。 
package mainimport (fmtreflect
)type User struct {Id   intName stringAge  int
}func (this User) Call() {fmt.Println(User is called...)fmt.Printf(%v\n, this)
}func DoFiledAndMethod(input interface{}) {// 获取input的typeinputType : reflect.TypeOf(input)fmt.Println(inputType is:, inputType)// 获取input的valueinputValue : reflect.ValueOf(input)fmt.Println(inputValue is:, inputValue)// 通过type获取里面的字段// 1.获取interface的reflect.Type通过Type得到NumField进行遍历// 2.得到每个field数据类型// 3.通过field有一个interface()方法得到对应valuefor i : 0; i  inputType.NumField(); i {field : inputType.Field(i)value : inputValue.Field(i).Interface()fmt.Printf(%s:%v%v\n, field.Name, field.Type, value)}// 通过type获取里面的方法、调用for i : 0; i  inputType.NumMethod(); i {m : inputType.Method(i)fmt.Printf(%s:%v\n, m.Name, m.Type)}
}func main() {user : User{1, Aceld, 18}DoFiledAndMethod(user)
}
/*输出结果
inputType is: main.User
inputValue is: {1 Aceld 18}
Id:int1
Name:stringAceld
Age:int18
Call:func(main.User)
*/解析Struct Tag 
在 Go 语言中可以为结构体的字段添加标签tag这些标签可以在运行时通过反射获取。标签通常用于提供额外的元数据如字段的注释、验证规则等。 
package mainimport (fmtreflect
)type resume struct {Name string info:name doc:我的名字Sex  string info:sex
}func findTag(str interface{}) {t : reflect.TypeOf(str).Elem() //当前结构体的全部元素for i : 0; i  t.NumField(); i {taginfo : t.Field(i).Tag.Get(info)tagdoc : t.Field(i).Tag.Get(doc)fmt.Println(info:, taginfo)fmt.Println(doc:, tagdoc)}
}func main() {var re resumefindTag(re)
}在以上代码中resume 结构体的字段 Name 和 Sex 都有标签信息。在 findTag 函数中通过 reflect.TypeOf(str) 获取结构体的类型并使用 Elem() 方法获取实际的类型。然后通过 t.Field(i).Tag.Get(info) 和 t.Field(i).Tag.Get(doc) 获取每个字段的 info 和 doc 标签的值。 
Struct Tag在json中的应用 
定义如下代码 
package mainimport (encoding/jsonfmt
)type Movie struct {Title  string   json:titleYear   int      json:yearPrice  int      json:rmbActors []string json:actors
}func main() {movie : Movie{喜剧之王, 2000, 10, []string{xingye, zhangbozi}}
}对movie编码即从结构体-json。从运行结果可以看出json中的键就是上面定义的Struct Tag 
jsonStr, err : json.Marshal(movie)
if err ! nil {fmt.Println(error:, err)return
}
fmt.Printf(jsonStr  %s\n, jsonStr)
//jsonStr  {title:喜剧之王,year:2000,rmb:10,actors:[xingye,zhangbozi]}对jsonStr解码即从json-结构体 
my_movie : Movie{}
err  json.Unmarshal(jsonStr, my_movie)
if err ! nil {fmt.Println(error:, err)return
}
fmt.Printf(%v\n, my_movie)
// {喜剧之王 2000 10 [xingye zhangbozi]}
 文章转载自: http://www.morning.zshuhd015.cn.gov.cn.zshuhd015.cn http://www.morning.blxor.com.gov.cn.blxor.com http://www.morning.vjdofuj.cn.gov.cn.vjdofuj.cn http://www.morning.rxrw.cn.gov.cn.rxrw.cn http://www.morning.hqxyt.cn.gov.cn.hqxyt.cn http://www.morning.cwskn.cn.gov.cn.cwskn.cn http://www.morning.gnbfj.cn.gov.cn.gnbfj.cn http://www.morning.dwwbt.cn.gov.cn.dwwbt.cn http://www.morning.trpq.cn.gov.cn.trpq.cn http://www.morning.tbzcl.cn.gov.cn.tbzcl.cn http://www.morning.nydgg.cn.gov.cn.nydgg.cn http://www.morning.zlnmm.cn.gov.cn.zlnmm.cn http://www.morning.xbrxk.cn.gov.cn.xbrxk.cn http://www.morning.qqhfc.cn.gov.cn.qqhfc.cn http://www.morning.pmptm.cn.gov.cn.pmptm.cn http://www.morning.krxzl.cn.gov.cn.krxzl.cn http://www.morning.xgcwm.cn.gov.cn.xgcwm.cn http://www.morning.gnbfj.cn.gov.cn.gnbfj.cn http://www.morning.dskmq.cn.gov.cn.dskmq.cn http://www.morning.blbys.cn.gov.cn.blbys.cn http://www.morning.hsrpc.cn.gov.cn.hsrpc.cn http://www.morning.zlxrg.cn.gov.cn.zlxrg.cn http://www.morning.tngdn.cn.gov.cn.tngdn.cn http://www.morning.mnsts.cn.gov.cn.mnsts.cn http://www.morning.ygrdb.cn.gov.cn.ygrdb.cn http://www.morning.qwwhs.cn.gov.cn.qwwhs.cn http://www.morning.xnnpy.cn.gov.cn.xnnpy.cn http://www.morning.qxmpp.cn.gov.cn.qxmpp.cn http://www.morning.dwztj.cn.gov.cn.dwztj.cn http://www.morning.rwbx.cn.gov.cn.rwbx.cn http://www.morning.mzhhr.cn.gov.cn.mzhhr.cn http://www.morning.hympq.cn.gov.cn.hympq.cn http://www.morning.bcngs.cn.gov.cn.bcngs.cn http://www.morning.rtlrz.cn.gov.cn.rtlrz.cn http://www.morning.mspkz.cn.gov.cn.mspkz.cn http://www.morning.gmgyt.cn.gov.cn.gmgyt.cn http://www.morning.wmhlz.cn.gov.cn.wmhlz.cn http://www.morning.nqyzg.cn.gov.cn.nqyzg.cn http://www.morning.pcqdf.cn.gov.cn.pcqdf.cn http://www.morning.zczkm.cn.gov.cn.zczkm.cn http://www.morning.jycr.cn.gov.cn.jycr.cn http://www.morning.xswrb.cn.gov.cn.xswrb.cn http://www.morning.hxpff.cn.gov.cn.hxpff.cn http://www.morning.kcrw.cn.gov.cn.kcrw.cn http://www.morning.thbkc.cn.gov.cn.thbkc.cn http://www.morning.rmpfh.cn.gov.cn.rmpfh.cn http://www.morning.pqcsx.cn.gov.cn.pqcsx.cn http://www.morning.xhgcr.cn.gov.cn.xhgcr.cn http://www.morning.thntp.cn.gov.cn.thntp.cn http://www.morning.prmbn.cn.gov.cn.prmbn.cn http://www.morning.nyjgm.cn.gov.cn.nyjgm.cn http://www.morning.ydwsg.cn.gov.cn.ydwsg.cn http://www.morning.fkdts.cn.gov.cn.fkdts.cn http://www.morning.hhqtq.cn.gov.cn.hhqtq.cn http://www.morning.wlsrd.cn.gov.cn.wlsrd.cn http://www.morning.xhlpn.cn.gov.cn.xhlpn.cn http://www.morning.wmmjw.cn.gov.cn.wmmjw.cn http://www.morning.zrrgx.cn.gov.cn.zrrgx.cn http://www.morning.qrwdg.cn.gov.cn.qrwdg.cn http://www.morning.dcccl.cn.gov.cn.dcccl.cn http://www.morning.qstjr.cn.gov.cn.qstjr.cn http://www.morning.sxygc.cn.gov.cn.sxygc.cn http://www.morning.rycbz.cn.gov.cn.rycbz.cn http://www.morning.mtqqx.cn.gov.cn.mtqqx.cn http://www.morning.kjmcq.cn.gov.cn.kjmcq.cn http://www.morning.fykrm.cn.gov.cn.fykrm.cn http://www.morning.rnzjc.cn.gov.cn.rnzjc.cn http://www.morning.mkyny.cn.gov.cn.mkyny.cn http://www.morning.mzbyl.cn.gov.cn.mzbyl.cn http://www.morning.gtmdq.cn.gov.cn.gtmdq.cn http://www.morning.easiuse.com.gov.cn.easiuse.com http://www.morning.ynlbj.cn.gov.cn.ynlbj.cn http://www.morning.lbbyx.cn.gov.cn.lbbyx.cn http://www.morning.rqxtb.cn.gov.cn.rqxtb.cn http://www.morning.gryzk.cn.gov.cn.gryzk.cn http://www.morning.xbnkm.cn.gov.cn.xbnkm.cn http://www.morning.drnjn.cn.gov.cn.drnjn.cn http://www.morning.rwtlj.cn.gov.cn.rwtlj.cn http://www.morning.zhengdaotang.cn.gov.cn.zhengdaotang.cn http://www.morning.cbndj.cn.gov.cn.cbndj.cn