成都便宜做网站的,昆明公司做网站的价格,郑州seo线下培训,建设网站时 首先要解决两个问题 一是什么目录 一、结构体
1、python 与 go面向对象的实现#xff1a;
2、初用GO中的结构体#xff1a;#xff08;实例化一个值类型的数据#xff08;结构体#xff09;#xff09;
输出结果不同的三种方式
3、实例化一个引用类型的数据#xff08;结构体#xff09;
4、…目录 一、结构体
1、python 与 go面向对象的实现
2、初用GO中的结构体实例化一个值类型的数据结构体
输出结果不同的三种方式
3、实例化一个引用类型的数据结构体
4、引用类型(指针类型) vs 值类型两者的区别
引用类型(指针类型) - 值类型内存拓扑图
5、结构体匿名字段、匿名结构体
6、结构体的嵌套
7、结构体转json类型
二、指针类型的种类结构体指针、数据变量指针、指针数组、数组指针
三、结构体方法(普通方法、指针方法)
四、结构体继承
五、结构体多态interface接口的运用
1、空接口的定义
2、接口如何实现自定义error呢
1、练习判断Role角色是否存活
2、练习实现发邮件功能
3、练习定义标准化返回json格式 一、结构体 结构体Struct是一种在Go语言中用于定义复合数据类型的机制。它允许你将不同类型的数据组合在一起形成一个自定义的数据类型以便更方便地管理和操作相关数据。 在Go语言中通过type关键字和字段列表来定义结构体。每个字段都可以有自己的数据类型类似于其他编程语言中的类的成员变量。结构体中的字段可以包含任意类型的数据包括基本数据类型如整数、浮点数、字符串等和其他自定义类型如其他结构体、数组、切片等。 结构体中可以定义多个字段类似于python中class类的属性 以下是一个简单的例子来说明如何定义和使用结构体 package mainimport fmt// 定义一个Person结构体
type Person struct {Name stringAge int
}func main() {// 创建一个Person类型的变量var person1 Person// 设置person1的字段值person1.Name Aliceperson1.Age 30// 打印person1的字段值fmt.Println(person1) // 输出{Alice 30}// 创建并初始化Person结构体的另一个变量person2 : Person{Name: Bob,Age: 25,}// 打印person2的字段值fmt.Println(person2) // 输出{Bob 25}
} 在上述示例中我们通过type关键字定义了一个名为Person的结构体。该结构体有两个字段分别为Name和Age分别用来存储人的姓名和年龄。 在main函数中我们创建了两个Person类型的变量person1和person2并分别设置了它们的字段值。可以通过运算符来访问结构体变量的字段。 1、python 与 go面向对象的实现 python 支持面向对象的 --》 class 类 go 不支持面向对象编程可以使用结构体来实现类似的功能 python 面向对象class Student(object):def __init__(self, id, name, age):self.id id....go 支持结构体
type struct_name struct{field_name1 field_typefield_name2 field_typefield_name3 field_type...
} 2、初用GO中的结构体实例化一个值类型的数据结构体
// 定义一个Student结构体
type Student struct {id intname stringage uintschool string
}func main(){// 实例化一实例化一个值类型的数据结构体// 实例化的时候可以只初始化部分数据zrp : Student{id: 1,name: zrp,}//输出结果不同的三种方式fmt.Printf(%v\n, zrp)fmt.Printf(%v\n, zrp)fmt.Printf(%#v\n, zrp)// 初始化的时候如果不指定字段名就需要每个字段都赋值// 否则会报错too few values in Student{…}wbw :Student{2,wbw,20, nongda}// 值类型的数据要看地址的话需要加fmt.Printf(%#v,地址%p\n, wbw, wbw)}输出
{1 zrp 0 }
{id:1 name:zrp age:0 school:}
main.Student{id:1, name:zrp, age:0x0, school:}
main.Student{id:2, name:wbw, age:0x14, school:nongda},地址0xc000100540
输出结果不同的三种方式 fmt.Printf(%v\n, zrp) fmt.Printf(%v\n, zrp) fmt.Printf(%#v\n, zrp) 输出 {1 zrp 0 } {id:1 name:zrp age:0 school:} main.Student{id:1, name:zrp, age:0x0, school:} 3、实例化一个引用类型的数据结构体
package mainimport fmt// 定义一个Student结构体
type Student struct {id intname stringage uintschool string
}func main(){// 实例化一个引用类型// 使用new实例化开辟一片内存空间创建一个实例对象返回这个对象的内存地址mq : new(Student) //使用new实例化开辟一片内存空间 , mq是引用类型的数据mq.id 3 //mq.name mqmq.age 18fmt.Printf(%#v,地址%p\n, mq, mq)
}输出
main.Student{id:3, name:mq, age:0x12, school:},0xc00000a028
4、引用类型(指针类型) vs 值类型两者的区别
package mainimport fmt// 定义一个Student结构体
type Student struct {id intname stringage uintschool string
}func main(){// 实例化一个值类型的数据wbw :Student{2,wbw,20, nongda}// 实例化一个引用类型的数据mq : new(Student)mq.id 3mq.name mqmq.age 18// 引用类型(指针类型) vs 值类型 区别// 引用类型 指向了一个内存数据注意如果要修改的话一同变化mq2 : mqmq2.name 米强fmt.Printf(type:%T,values:%v,address:%p\n,mq, mq,mq)fmt.Printf(type:%T,values:%v,address:%p\n,mq2, mq2,mq2)// 值类型两份数据相互不影响wbw2 : wbwwbw2.name 王百文fmt.Printf(type:%T,values:%v,address:%p\n,wbw, wbw, wbw)fmt.Printf(type:%T,values:%v,address:%p\n,wbw2, wbw2,wbw2)
}输出
type:*main.Student,values:{id:3 name:米强 age:18 school:},address:0xc0001004e0
type:*main.Student,values:{id:3 name:米强 age:18 school:},address:0xc0001004e0
type:main.Student,values:{id:2 name:wbw age:20 school:nongda},address:0xc0001004b0
type:main.Student,values:{id:2 name:王百文 age:20 school:nongda},address:0xc000100570引用类型(指针类型) - 值类型内存拓扑图 5、结构体匿名字段、匿名结构体
package mainimport fmt// 结构体匿名字段 如果没有定义字段名会用类型的名字直接充当字段名
type Stu struct {stringint
}func main(){// 结构体匿名字段实例化st1 : Stu{abc, 100}fmt.Printf(st1:%v\n, st1)// 匿名结构体: 适合一次性使用stu2 : struct {name stringage int}{cali, 30}fmt.Printf(st2:%v\n, stu2)
}输出
st1:{string:abc int:100}
st2:{name:cali age:30}
6、结构体的嵌套
package mainimport fmt// 结构体的嵌套
type Book struct {title stringAuthor struct{name, tel stringage int}
}func main(){// 嵌套结构体的实例化b1 : Book{title: GO从入门到精通}b1.Author.name cicib1.Author.tel 186xxxxxxxxfmt.Printf(b1:%v\n, b1)
}输出
b1:{title:GO从入门到精通 Author:{name:cici tel:186xxxxxxxx age:0}}
7、结构体转json类型
package mainimport (encoding/jsonfmt
)// Web开发数据定义都是结构体类型 结构体数据 json 前端
// 加Tag两个反引号: Tag加上json配置项他当将结构体转换成json的时候读取该配置
// Student结构体内的数据转换为json格式
type Student struct{// 转换json格式Id int json:idName string json:username// 设置成“-” 表示忽略该字段School string json:-// 如果没有配置 使用默认字段名School2 string// omitempty如果当前字段School3有值的会显示出来如果没有值就不会显示School3 string json:school,omitempty
}// 使用json模块
// go结构体数据 json 前端
func main(){// 实例化s1 : Student{Id: 1,Name: user1,School: nongda,School3: nongda3, // omitempty会导致如果School3没有值就不会显示School3字段}// 用于进行go的异常处理bmarshal, err : json.Marshal(s1)if err nil {// 输出转换后的json格式数据fmt.Println(string(bmarshal))}else{// 输出其中的错误fmt.Println(err:, err)}
}输出
{id:1,username:user1,School2:,school:nongda2}
二、指针类型的种类结构体指针、数据变量指针、指针数组、数组指针
package mainimport fmt// 定义一个Student结构体
type Student struct {id intname stringage uintschool string
}func main(){// 结构体指针mc : Student{id: 4,name: mc,}fmt.Printf(type:%T, values:%v\n, mc, mc)// 结构体指针中可以使用简化的语法fmt.Printf(%v, %s\n, mc, (*mc).name)fmt.Printf(%v, %s\n, mc, mc.name)// 数据变量指针获取数据的方法var n1 *int // 定义n1为int指针n2 : 10 // 给n2赋值n1 n2 // 将n2的地址传给n1指针*n1 20 // 给n1指针赋值为20fmt.Printf(type:%T,address:%p, value:%d\n,n1, n1, *n1)fmt.Printf(address:%p, value:%d\n,n2, n2)// 指针数组 parr是一个数组有4个元素每个元素都是一个int类型的指针var parr [4]*inta : 10parr[2] afmt.Printf(value:%v, address:%v\n, *parr[2], parr[2])// 数组指针是一个指针指向了一个数组类型的数据访问数据的时候可以使用简化方式var parr2 *[4]intarr : [4]int{1,2,3,4}parr2 arrfmt.Printf(arrvalue:%v, value:%v, value:%v\n, parr2, (*parr2)[0], parr2[0])
}输出
type:*main.Student, values:{id:4 name:mc age:0 school:}
type:*int,address:0xc0000a60a0, value:20
address:0xc0000a60a0, value:20
{id:4 name:mc age:0 school:}, mc
{id:4 name:mc age:0 school:}, mc
value:10, address:0xc00000e138
arrvalue:[1 2 3 4], value:1, value:1三、结构体方法(普通方法、指针方法)
package mainimport fmt
// 结构体方法的实现
// 在普通函数前加上一个接收者(receiver)
// func (s receiverType) funcName(args...) --》 结构体方法的定义// 定义一个Student结构体
type Student struct {id intname stringage uintschool string
}// 为Student结构绑定一个changeSchool方法 值类型的结构体在函数内部修改数据并不会影响函数外面
func (s Student) changeSchool(school string){s.school school
}// 为*Student指针结构体绑定一个changeSchool2方法 指针类型的结构体在函数中修改了数据会影响外部的数据
func (s *Student) changeSchool2(school string){s.school school
}// 因此我们在调用结构体方法的时候需要注意是什么结构体类型
func main(){// 实例化一个值类型的数据// 实例化一个结构体// 实例化的时候可以只初始化部分数据zrp : Student{id: 1,name: zrp,} // 结构体指针mc : Student{id: 4,name: mc,}// 使用结构体方法// 值结构(普通结构体)// 普通结构外面的数据和函数中的数据是两个不同的数据在函数内修改不影响函数外zrp.changeSchool(湖南农业大学)fmt.Printf(新学校是:%v\n, zrp.school)// 输出为新学校是: 没有传入值// 指针结构体外面和函数中是同一个数据在函数中修改了影响函数外mc.changeSchool2(湖南农业大学)fmt.Printf(新学校是:%v\n, mc.school)}输出
新学校是:
新学校是:湖南农业大学
四、结构体继承
package mainimport fmt// 创建Author作者结构体
type Author struct{// 定义字段name, tel stringage int
}// 继承Book继承了Author结构体
type Book struct {title stringauthor Author
}// 给Book添加了一个结构体方法
func (b *Book) Print(){ fmt.Printf(%s的作者是%s\n, b.title, b.author.name)
}func main(){// 实例化方法// 先实例化Book在将Author继承给Bookb1 : Book{title: 《Go入门到精通》}b1.author.name TeacherWenb1.author.tel 187xxxxxxxfmt.Printf(%v\n,b1)b1.Print()// 先实例化Author, 再把Author赋值给Booka1 : Author{name: TeacherFeng}b2 : Book{title: 《Docker从入门到精通》, author: a1}fmt.Printf(%v\n,b2)b2.Print()
}输出
{title:《Go入门到精通》 author:{name:TeacherWen tel:187xxxxxxx age:0}}
《Go入门到精通》的作者是TeacherWen
{title:《Docker从入门到精通》 author:{name:TeacherFeng tel: age:0}}
《Docker从入门到精通》的作者是TeacherFeng
五、结构体多态interface接口的运用 多态一个接口多个形态为多个不同的数据类型提供统一的接口 其实就是一个功能展现多种形态 多态是指同一种操作或方法可以在不同的对象上产生不同的行为。 Go语言中实现多态需要用到interface Interface接口类型可以定义一组方法而非变量并且不需要实现 // 定义一个函数MyPrint我们可以通过MyPrint来使多个数据进行打印操作但是当前MyPrint并不是多态的需要下面的interface接口操作
// func MyPrint(s string){
// fmt.Println()
// }// 如果WePay结构体实现了PayInterface接口所有的方法那么可以说
// WePay结构是是PayInterface类型
type PayInterface interface {// 声明一些方法但不需要实现// 方法名(参数列表) 返回值 --》pay()就为方法接口他没有参数和返回值pay()// 可以定义多个方法接口// pay2()、// print()// 运行print()方法后报错AliPay does not implement PayInterface (missing print method) 和 WePay does not implement PayInterface (missing print method)// 说明AliPay 和 WePay 没有实现print() 方法// 如果说WePay结构体和AliPay结构体实现了PayInterface接口所有的方法那么可以说这个结构体是PayInterface的可以实现的接口类型。// 下面我们将要实现微信支付和支付宝支付操作// 定义微信支付结构体
type WePay struct {name string
}// WePay实现了pay方法 等于 WePay实现PayInterface接口wepay可以看作是PayInterface类型上面定义的interface接口类型结构体
func (w WePay) pay(){fmt.Printf(This is WePay:%s\n, w.name)
}// 定义支付宝支付结构体
type AliPay struct {name string
}// AliPay实现PayInterface接口
func (a AliPay) pay(){fmt.Printf(This is AliPay:%s\n, a.name)
}// 定义函数payment用于实现PayInterface接口的pay()方法
func payment(p PayInterface){p.pay()
}func main(){// 实例化w1 和 a1分别用于微信支付和支付宝支付w1 : WePay{name: cici}a1 : AliPay{name: aiai}// 调用payment函数传入实例实现WePay和AliPay payment(w1)payment(a1)
}输出
This is WePay:cici
This is AliPay:aiai
1、空接口的定义 空接口可以表示任意类型的值。空接口的作用在于可以在不确定类型的情况下用于保存和传递各种不同类型的值。由于空接口可以表示任意类型的值所以它在某些场景下非常有用比如在函数参数中可以接受不同类型的参数或者在数据结构中可以存储不同类型的元素。 package mainimport fmt// 空接口
type Empty interface {}// 该test函数可以接收任意类型的数据空接口的定义方式
func test(f interface{}){fmt.Printf(%v\n,f)
}func main(){// 空接口的使用// 该实例希望它的方法是string类型但是它的value值可以是任意类型的如希望m1定义为m1 {name:cici, age:20}这种value可以是任意类型的因此我们可以定义一个空接口Empty interface// Empty结构体定义方式m1 :map[string]Empty{name:cici,age: 20,}//interface{}方法定义方式m2 :map[string]interface{}{name:aiai,age: 18,}fmt.Printf(%v\n%v\n, m1, m2)
}输出
map[age:20 name:cici]
map[age:18 name:aiai]2、接口如何实现自定义error呢
package mainimport (fmt//errors
)// 定义NameCheck函数用于返回Error使用
// 如果name值为空返回一个错误否则就返回nil
func NameCheck(name string) error { // 返回数据的类型是error类型if name {// return errors.New(名字不能为空) // 通过errors包内New函数来进行error的提示, 比较复杂// 输出为名字不能为空// 进行自定义错误优点是比errors包内调用New方法简单快捷很多return NameEmptyError{msg:名字不能为空, code:1001}// 输出为出错了:名字不能为空}return nil
}// 自定义错误 给NameEmptyError实现一个Error方法它就是一个error类型了
type NameEmptyError struct {msg stringcode int
}// 定义NameEmptyError结构体方法Error()
func (e NameEmptyError) Error() string{// e.msg表示错误的信息return 出错了:e.msg
}func main(){// 定义变量namename : // 调用NameCheck函数err : NameCheck(name)if err ! nil{// 出现错误输出错误fmt.Println(err)}else{fmt.Println(name)}
}
1、练习判断Role角色是否存活 定义Role角色 属性name, blood, isAlive是否存活 isAlive 判断blood是0 True or False package mainimport fmt// 定义结构体
type Role struct {name stringblood int
}// 非指针型的绑定将r 绑定为 Role 结构体 isAlive() 是一个函数
func (r Role) isAlive() bool{if r.blood 0{return false}else{return true}
}// 指针型的绑定
//func (r *Role) isAlive() bool {
// if r.blood 0{
// return false
// }else{
// return true
// }
//}func main(){// 创建实例类型role1 : Role{role1, 90}role2 : Role{role2, 0}// 打印数据fmt.Printf(%s:%v\n, role1.name, role1.isAlive())fmt.Printf(%s:%v\n, role2.name, role2.isAlive())
}输出
role1:true
role2:false
2、练习实现发邮件功能 功能介绍 普通用户结构体User 字段username, email, ShowUserInfo(), SendMail() Root用户结构体Root 字段username, email, ShowSysInfo(), SendMail() 邮件告警的功能 sendNotification函数 --》可以接受所有权限用户 普通用户User和Root用户都能够使用sendNotification函数 并实现对对象的SendMail() package mainimport fmt// 定义User结构体内存字段username用户名、email邮件地址
type User struct {username stringemail string
}// 定义Root结构体内存字段username用户名、email邮件地址
type Root struct {username stringemail string
}// 定义ShowUserInfo()结构体方法调用User结构体实现展示用户信息的功能
func (u User) ShowUserInfo(){fmt.Println(这是User的userInfo, User为, u.username)
}// 定义SendMail()结构体方法调用User结构体实现发送用户邮件的功能
func (u User) SendMail(){fmt.Printf(User:%s正在发送邮件到%s\n, u.username, u.email)
}// 定义ShowSysInfo()结构体方法调用Root结构体实现展示Root信息的功能
func (r Root) ShowSysInfo(){fmt.Println(这是Root的sysInfo, Root为, r.username)
}// 定义SendMail()结构体方法调用Root结构体实现Root发送邮件的功能
func (r Root) SendMail(){fmt.Printf(Root:%s正在发送邮件到%s\n, r.username, r.email)
}// 定义SendMailInterface结构体内存SendMail()结构体方法
type SendMailInterface interface {SendMail()
}// 定义sendNotification函数作用是接收参数并作为SendMail的对象
func sendNotification(s SendMailInterface){s.SendMail()
}func main() {// 结构体实例化r : Root{username: root, email: rootsc.com}u : User{username: user1, email: user1sc.com}// 调用sendNotification函数并传入实例参数r.ShowSysInfo()sendNotification(r)u.ShowUserInfo()sendNotification(u)
}输出
这是Root的sysInfo, Root为 root
Root:root正在发送邮件到rootsc.com
这是User的userInfo, User为 user1
User:user1正在发送邮件到user1sc.com3、练习定义标准化返回json格式
package main/*
// 定义返回的数据格式将返回的数据用json的方式打印出来
// Code, Message, Data
// s.json() 将它转换成json格式string后端开发API 访问url 返回数据无页面 访问者
标准化返回
{”code: 1001,message: 参数不完整“,data: {}/[]/other
}
*/