广东省建设工程质量安全监督检测总站网站手机网页无法打开因为reset
web/
2025/9/28 5:03:21/
文章来源:
广东省建设工程质量安全监督检测总站网站,手机网页无法打开因为reset,安装wordpress到服务器,代理注册公司哪里好1.简介
go也支持面向对象编程(OOP)#xff0c;但是和传统的面向对象编程有区别#xff0c;并不是纯粹的面向对象语言。所以说go支持面向对象编程特性是比较准确的。go没有类(class)#xff0c;go语言的结构体(struct)和其它编程语言的类(class)有同等的地位#xff0c;你可…1.简介
go也支持面向对象编程(OOP)但是和传统的面向对象编程有区别并不是纯粹的面向对象语言。所以说go支持面向对象编程特性是比较准确的。go没有类(class)go语言的结构体(struct)和其它编程语言的类(class)有同等的地位你可以理解go是基于struct来实现OOP特性的。go面向对象编程非常简洁去掉了传统OOP语言的继承、方法重载、构造函数和析构函数、隐藏的this指针等。go仍然有面向对象编程的继承、封装和多态的特性只是实现的方式和其他OOP语言不一样比如继承go没有extends关键字继承是通过匿名字段来实现。go面向对象(OOP)很优雅OOP本身就是语言类型系统(type system)的一部分通过接口(interface)关联耦合性低也非常灵活。也就是说在go中面向接口编程是非常重要的特性。
2.type关键词自定义类型和类型别名
2.1自定义类型
在go语言中有一些基本的数据类型比如string、int、bool等数据类型可以用type关键字自定义类型。
语法 type comstomInt int 将comstomInt 定义为int类型通过type关键字的定义comstomInt就是一种新的类型comstomInt和int不是同一类型它具有int的特性。 type comstomInt int var a comstomInt 3var b int 3fmt.Printf(a:%v %T\n, a, a) //a:3 main.comstomIntfmt.Printf(b:%v %T\n, b, b) //b:3 int
2.2类型别名
类型别名规定TypeAlias只是Type的别名本质上TypeAlias与Type是同一类型。就像外号和真实姓名都是指的同一个人。
语法 type intAliasint
我们之前见过的rune和byte就是类型别名
type byte uint8
type rune int32
2.3自定义类型和类型别名的区别
类型别名与自定类型表面上看只有一个等号的差异我们通过下面的这段代码来理解他们之间的却别。
type comstomInt int
type intAlias intfunc main() {var a intAlias 3fmt.Printf(a:%v %T\n, a, a) //a:3 intvar b comstomInt 3fmt.Printf(b:%v %T\n, b, b) //b:3 main.comstomInt
}
结果显示a的类型时int类型。b的类型时main.comstomInt,表示main包下定义的comstomInt类型。
3.结构体的定义
使用type和struct关键字来定义结构体语法如下
type 类型名 struct{
属性1 类型
属性2 类型
...
}
解释
类型名表示自定义结构体的名称在一个包内不能重复。首字母大写可以外部访问属性表示结构体字段名结构体中的字段必须唯一。首字母大写可以外部访问类型表示结构体属性的具体类型。 举个例子我们定义一个学生Student的结构体
type Student struct {Name stringNumber intSex intAge int
} 同样类型的字段也可以写在一行。
type Student struct {Name stringNumber,Sex,Age int
}4.结构体的实例化
简述只有当结构体实例化时才会真正地分配内存。也就是必须示例化以后才能使用结构体的字段。
结构体是自定义的数据类型代表一类事物。结构体变量实例是具体的实际的代表一个具体变量。同一个结构体变量实例之间是相对独立的变量不会相互影响。
4.1第一种方法
结构体本身也是一种数据类型我们可以像声明内置类型一样使用var关键字声明结构提类型。
var 结构体实例 结构体类型
type Student struct {Name string //姓名Number int //学号
}func main() {var s1 Students1.Name 韩梅梅s1.Number 20250306123fmt.Printf(s1%#v\n, s1)//s1main.Student{Name:韩梅梅, Number:20250306123}
}
4.2第二种方法 可以通过new关键字对结构体进行实例化得到的是具体的地址。
type Student struct {Name string //姓名Number int //学号
}func main() {s1 : new(Student)s1.Name 韩梅梅s1.Number 20250306123fmt.Printf(s1%#v\n, s1) //s1main.Student{Name:韩梅梅, Number:20250306123}fmt.Println(s1.Name) //韩梅梅fmt.Println((*s1).Name) //韩梅梅
}
从结果可以看出s1是一个结构体指针。
注意在go中支持对结构体指针直接使用点.来访问结构体成员。s1. Name和(*s1).Name输出是一样的go设计者为了程序员使用方便底层会对结构体进行处理。
4.3第三种方法
使用对结构体进行取地址操作相当于对该结构体类型进行了new的实例化操作。
type Student struct {Name string //姓名Number int //学号
}func main() {s1 : Student{}s1.Name 韩梅梅s1.Number 20250306123fmt.Printf(s1%#v\n, s1) //s1main.Student{Name:韩梅梅, Number:20250306123}fmt.Println(s1.Name) //韩梅梅fmt.Println((*s1).Name) //韩梅梅
}
4.4第四种方法 键值对初始化
type Student struct {Name string //姓名Number int //学号
}func main() {s1 : Student{Name: 蕾蕾,Number: 20250306123,}fmt.Printf(s1%#v\n, s1) //s1main.Student{Name:蕾蕾, Number:20250306123}fmt.Println(s1.Name) //蕾蕾
}
4.5第五种方法 结构体指针进行键值对初始化
type Student struct {Name string //姓名Number int //学号
}func main() {s1 : Student{Name: 蕾蕾,}fmt.Printf(s1%#v\n, s1) //s1main.Student{Name:蕾蕾, Number:0}fmt.Println(s1.Name) //蕾蕾fmt.Println((*s1).Name) //蕾蕾
}
注意在创建一个结构体变量后如果没有给字段赋值都对应一个零值默认值。
布尔类型是false数值是0字符串是“”。
数组类型的默认值和它的元素类型相关比如score[3]int 则为[000]。
指针slice和map的零值都是nil即还没有分配空间。如果需要使用这样的字段需要先make才能使用。
4.6第六种方法
使用列表初始化也就是初始化的时候不写键直接写值。
注意
必须初始化结构体的所有字段。初始化的填充顺序必须与字段在结构体中的声明顺序一致。该初始化不能和键值初始化方式混用。
type Student struct {Name string //姓名Number int //学号}func main() {s1 : Student{蕾蕾,1234567890,}fmt.Printf(s1%#v\n, s1) //s1main.Student{Name:蕾蕾, Number:1234567890}fmt.Println(s1.Name) //蕾蕾fmt.Println((*s1).Name) //蕾蕾
}
5.结构体的方法和接收者
5.1结构体是值类型
package mainimport fmttype Person struct {Name stringAge int
}func main() {p1 : Person{小王子,18,}p2 : p1p2.Name kingsfmt.Printf(%#v\n, p1) //main.Person{string:小王子, int:18}fmt.Printf(%#v\n, p2) //main.Person{Name:kings, Age:18}
}在go语言中没有类的概念但是可以给类型结构体自定义类型定义方法。所谓方法 就是定义了接收者的函数。接收者的概念就类似于其他语言中的this或者 self。
方法的定义格式如下
func (接收者变量 接收者类型) 方法名(参数列表) (返回参数) { 函数体 }
其中
接收者变量接收者中的参数变量名在命名时官方建议使用接收者类型名的第一个小 写字母而不是self、this之类的命名。例如Person类型的接收者变量应该命名为 p Connector 类型的接收者变量应该命名为c等。接收者类型接收者类型和参数类似可以是指针类型和非指针类型。方法名、参数列表、返回参数具体格式与函数定义相同。
给结构体Person定义一个方法打印Person的信息
package mainimport fmttype Person struct {name stringage int8
}func (p Person) printInfo() {fmt.Printf(姓名:%v 年龄:%v, p.name, p.age)
}
func main() {p1 : Person{name: 李雷,age: 15,}p1.printInfo() //姓名:李雷 年龄:15
}对上面类型说明 func (p Person) printInfo() {} 表示Person结构体有一方法方法名为printInfo。(p Person)体现printInfo方法是和Person类型绑定的。printInfo方法只能通过Person类型的变量调用而不能直接调用也不能使用其他类型变量来调用。 func (p Person) printInfo() {} p表示那么Person变量调用这个p就是它的副本这点和函数传参非常相似。
5.2值类型的接收者
当方法作用于值类型接收者时Go语言会在代码运行时将接收者的值复制一份。在值类型 接收者的方法中可以获取接收者的成员值但修改操作只是针对副本无法修改接收者变量 本身。
5.3指针类型的接收者
指针类型的接收者由一个结构体的指针组成由于指针的特性调用方法时修改接收者指针 的任意成员变量在方法结束后修改都是有效的。这种方式就十分接近于其他语言中面向 对象中的this或者self。
package mainimport fmttype Person struct {name stringage int
}// 值类型接受者
func (p Person) printInfo() {fmt.Printf(姓名:%v年龄:%v\n, p.name, p.age)
}// 指针类型接收者
func (p *Person) setInfo(name string, age int) {p.name namep.age age
}
func main() {p1 : Person{name: 小王子,age: 25,}p1.printInfo() //姓名:小王子年龄:25p1.setInfo(张三, 20)p1.printInfo() //姓名:张三年龄:20
}6.给任意类型添加方法 在Go语言中接收者的类型可以是任何类型不仅仅是结构体任何类型都可以拥有方法。 举个例子我们基于内置的int类型使用type关键字可以定义新的自定义类型然后为我们 的自定义类型添加方法。
package mainimport fmttype myInt intfunc (m myInt) SayHello() {fmt.Println(Hello,我是一个int。)
}
func main() {var m1 myIntm1.SayHello() //Hello,我是一个int。m1 100fmt.Printf(%#v %T\n, m1, m1) //100 main.MyInt
}注意事项非本地类型不能定义方法也就是说我们不能给别的包的类型定义方法。
7.结构体的匿名字段 结构体允许其成员字段在声明时没有字段名而只有类型这种没有名字的字段就称为匿名字 段。 import fmttype Person struct {stringint
}func main() {p1 : Person{小王子,18,}fmt.Printf(%#v\n, p1) //main.Person{string:小王子, int:18}fmt.Println(p1.string, p1.int) //小王子 18
}匿名字段默认采用类型名作为字段名结构体要求字段名称必须唯一因此一个结构体中同 种类型的匿名字段只能有一个。
8.嵌套结构体
一个结构体中可以嵌套包含另一个结构体或者结构体指针。
package mainimport fmttype Address struct {City stringPhone string
}
type User struct {Name stringSex stringAddressKey Address
}
func main() {user : User{Name: 张三,Sex: 男,AddressKey: Address{City: 杭州,Phone: 132*****321,},}fmt.Printf(%#v\n, user)//main.User{Name:张三, Sex:男, AddressKey:main.Address{City:杭州, Phone:132*****321}}
}9.嵌套匿名结构体
package mainimport fmttype Address struct {City stringPhone string
}
type User struct {Name stringSex stringAddress //匿名结构体
}func main() {user : User{Name: 张三,Sex: 男,Address: Address{City: 杭州,Phone: 132*****321,},}user.Address.City 北京 //通过匿名结构体.字段名访问user.City 上海 //直接访问匿名结构体的字段名fmt.Printf(%#v\n, user) //main.User{Name:张三, Sex:男, AddressKey:main.Address{City:杭州, Phone:132*****321}}
}注意当访问结构体成员时会先在结构体中查找该字段找不到再去匿名结构体中查找。
10.嵌套匿名结构体的字段名冲突
package mainimport (fmttime
)type Address struct {City stringPhone stringCreateTime string
}
type Email struct {Acount stringCreateTime string
}
type User struct {Name stringSex stringAddress //匿名结构体Email //匿名结构体
}func main() {user : User{Name: 张三,Sex: 男,Address: Address{City: 杭州,Phone: 132*****321,},}user.Email.CreateTime time.Now().Format(2006-01-02 03:04:05)//指定Email结构体中的CreateTimeuser.Address.CreateTime time.Now().Format(2006-01-02 03:04:05)//指定Address结构体中的VreateTimefmt.Printf(%#v\n, user) //main.User{Name:张三, Sex:男, Address:main.Address{City:杭州, Phone:132*****321, CreateTime:2025-03-16 05:49:43}, Email:main.Email{Acount:, CreateTime:2025-03-16 05:49:43}}
}注意嵌套结构体内可能存在相同的字段名称这时候为了避免歧义需要自定具体的嵌套结构体字段。
11.结构体的继承
go语言中使用结构体也可以实现其他编程语言中的继承关系利用匿名结构体嵌套实现继承。
package mainimport fmttype Animal struct {Name string
}func (receiver Animal) printName() {fmt.Println(名字, receiver.Name)
}type Dog struct {Color stringAge int*Animal
}func main() {dog : Dog{}dog.Animal Animal{Name: 大黄,}dog.printName() //名字大黄
}12.json数据
JSON是一种轻量级的数据交换格式易于阅读和编写同时也易于机器解析和生成。
json的基本格式 {avgSeatView: 4.8%,avgShowView: 7.5,boxRate: 58.6%,boxSplitUnit: {num: #xefe9;#xf70e;#xe85f;#xe85f;.#xefe9;#xed4f;,unit: 万},movieInfo: {movieId: 1294273,movieName: 哪吒之魔童闹海,releaseInfo: 上映47天},showCount: 142769,showCountRate: 36.1%,splitBoxRate: 59.0%,splitBoxSplitUnit: {num: #xefe9;#xf0f0;#xe85f;#xf70e;.#xed4f;#xf7b3;,unit: 万},sumBoxDesc: 148.58亿,sumSplitBoxDesc: 134.35亿}
13.结构体与JSON序列化
go json序列化是指把结构体数据转化成json格式的字符串go json的反序列化是指把json数据转化成go中的结构体对象。
go中的序列化和反序列化主要通过“encoding/json”包中的json.Marshal()和json.Unmarshal()方法实现。
13.1结构体转JSON字符串
package mainimport (encoding/jsonfmt
)type Persion struct {ID intSex stringName stringHobby []string
}func main() {p : Persion{ID: 10001,Sex: 男,Name: 赵六,Hobby: []string{篮球, 足球, 羽毛球},}fmt.Printf(%#v\n, p) //main.Persion{ID:10001, Sex:男, Name:赵六, Hobby:[]string{篮球, 足球, 羽毛球}}by, err : json.Marshal(p)if err ! nil {fmt.Println(转译错误!!)} else {fmt.Println(string(by)) //{ID:10001,Sex:男,Name:赵六,Hobby:[篮球,足球,羽毛球]}}
}13.2json字符串转换成结构体对象
package mainimport (encoding/jsonfmt
)type Persion struct {ID intSex stringName stringHobby []string
}func main() {str : {ID:10001,Sex:男,Name:赵六,Hobby:[篮球,足球,羽毛球]}var p Persionerr : json.Unmarshal([]byte(str), p)if err ! nil {fmt.Println(序列化错误)} else {fmt.Printf(%#v\n, p) //main.Persion{ID:10001, Sex:男, Name:赵六, Hobby:[]string{篮球, 足球, 羽毛球}}}
}14.结构体标签tag
Tag是结构体的元素信息可以在运行的时候通过反射的机制读取出来。tag在结构体字段的后方定义由一对反引号包裹起来具体格式如下
key1:value1 key2:value2
结构体tag由一个或多个键值组成。键与值使用冒号分隔值用双引号括起来。同一个结构体字段可以设置多个键值对tag不同的键值对之间使用空格分隔。
注意事项为结构体编写tag时必须严格遵守键值对的规则。结构体标签的解析代码的容错能力很差一旦格式写错编译和运行时都不会提示任何错误通过反射也无法正确取值列如不要在key和value之间添加空格。
14.结构体转json字符串
package mainimport (encoding/jsonfmt
)type Persion struct {ID int json:id //通过指定tag实现json序列化该字段时keyidSex string json:sexName string json:nameHobby []string json:hobby
}func main() {p : Persion{ID: 10001,Sex: 男,Name: 赵六,Hobby: []string{篮球, 足球, 羽毛球},}by, err : json.Marshal(p)if err ! nil {fmt.Println(转译错误!!)} else {fmt.Println(string(by)) // {id:10001,sex:男,name:赵六,hobby:[篮球,足球,羽毛球]}}
}
14.2json字符串转化成结构体
package mainimport (encoding/jsonfmt
)type Persion struct {ID int json:id //通过指定tag实现json序列化该字段时keyidSex string json:sexName string json:nameHobby []string json:hobby
}func main() {str : {id:10001,sex:男,name:赵六,hobby:[篮球,足球,羽毛球]}var p Persionerr : json.Unmarshal([]byte(str), p)if err ! nil {fmt.Println(序列化错误)} else {fmt.Printf(%#v\n, p) //main.Persion{ID:10001, Sex:男, Name:赵六, Hobby:[]string{篮球, 足球, 羽毛球}}}
}15.嵌套结构体和json序列化反序列化
15.1结构体转化成json字符串 package mainimport (encoding/jsonfmt
)type Student struct {ID int json:id //通过指定tag实现json序列化该字段时keyidSex string json:sexName string json:nameHobby []string json:hobby
}
type Class struct {No string json:noStudent []Student json:student
}func main() {var cl Classcl.No 六年级一班stu : make([]Student, 0)for i : 0; i 10; i {s : Student{ID: 1000 i,Sex: 男,Name: fmt.Sprintf(王五%v, i),Hobby: []string{java, php, golang},}stu append(stu, s)}cl.Student stuby, err : json.Marshal(cl)if err ! nil {fmt.Println(转译错误)} else {fmt.Println(string(by))}
}结果
{no:六年级一班,student:[{id:1000,sex:男,name:王五0,hobby:[java,php,golang]},{id:1001,sex:男,name:王五1,hobby:[java,php,golang]},{id:1002,sex:男,name:王五2,hobby:[java,php,golang]},{id:1003,sex:男,name:王五3,hobby:[java,php,golang]},{id:1004,sex:男,name:王五4,hobby:[java,php,golang]},{id:1005,sex:男,name:王五5,hobby:[java,php,golang]},{id:1006,sex:男,name:王五6,hobby:[java,php,golang]},{id:1007,sex:男,name:王五7,hobby:[java,php,golang]},{id:1008,sex:男,name:王五8,hobby:[java,php,golang]},{id:1009,sex:男,name:王五9,hobby:[java,php,golang]}]}15.2json字符串转化成结构体
package mainimport (encoding/jsonfmt
)type Student struct {ID int json:id //通过指定tag实现json序列化该字段时keyidSex string json:sexName string json:nameHobby []string json:hobby
}
type Class struct {No string json:noStudent []Student json:student
}func main() {str : {no:六年级一班,student:[{id:1000,sex:男,name:王五0,hobby:[java,php,golang]},{id:1001,sex:男,name:王五1,hobby:[java,php,golang]},{id:1002,sex:男,name:王五2,hobby:[java,php,golang]},{id:1003,sex:男,name:王五3,hobby:[java,php,golang]},{id:1004,sex:男,name:王五4,hobby:[java,php,golang]},{id:1005,sex:男,name:王五5,hobby:[java,php,golang]},{id:1006,sex:男,name:王五6,hobby:[java,php,golang]},{id:1007,sex:男,name:王五7,hobby:[java,php,golang]},{id:1008,sex:男,name:王五8,hobby:[java,php,golang]},{id:1009,sex:男,name:王五9,hobby:[java,php,golang]}]}
var cl Classerr : json.Unmarshal([]byte(str), cl)if err ! nil {fmt.Println(序列化错误)} else {fmt.Printf(%#v, cl)}
}结果
main.Class{No:六年级一班, Student:[]main.Student{main.Student{ID:1000, Sex:男, Name:王五0, Hobby:[]string{java, php, golang}}, main.Student{ID:1001, Sex:男, Name:王五1, Hobby:[]string{java, php, golang}}, main.Student{ID:1002, Sex:男, Name:王五2, Hobby:[]string{java, php, golang}}, main.Student{ID:1003, Sex:男, Name:王五3, Hobby:[]string{java, php, golang}}, main.Student{ID:1004, Sex:男, Name:王五4, Hobby:[]string{java, php, golang}}, main.Student{ID:1005, Sex:男, Name:王五5, Hobby:[]string{java, php, golang}}, main.Student{ID:1006, Sex:男, Name:王五6, Hobby:[]string{java, php, golang}}, main.Student{ID:1007, Sex:男, Name:王五7, Hobby:[]string{java, php, golang}}, main.Student{ID:1008, Sex:男, Name:王五8, Hobby:[]string{java, php, golang}}, main.Student{ID:1009, Sex:男, Name:王五9, Hobby:[]string{java, php, golang}}}}
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/83144.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!