一、类型和结构体
基于已有类型(string)定义的类型
具有原类型(string)的特性,并且可以扩展自己想要的特性
<code>type myString string/<code>
为类型(string)定义别名
新和原有在使用上完全一样,但是在编译后运行时,别名将不存在,进而替换成原类型名
<code>type aliasString = string
//比如下面之前遇到的
type byte = uint8
type rune = int32/<code>
自定义新的结构体,语法如下
type myType struct {
fieldName fieldType
fieldName fieldType
...
}
<code>//举例type student struct {
name string
class string
age int
score int
}
//相同类型可以简写如下,和函数的多参数类型一样可简写
type student1 struct {
name,class string
age,score int
}
//结构体对应的构造函数用来初始化结构体
//本质就是普通的函数,只不过约定成俗叫构造函数
func newStudent(name,class string,age int)*student {
return &student{
name: name,
class: class,
age: age,
}
}/<code>
- 结构体的实例化1,结构体占用一块连续的内存(先记忆着)
<code>var stu student
stu.name="student name"
stu.age=18/<code>
- 结构体的实例化2,可以使用键值对选择初始化自己需要的字段
<code>stu1 := student{
name: "name",
class: "class",
age: 18, score: 100,}/<code>
- 结构体的实例化3,按列表方式初始化,这种方式需要初始化全部字段
<code>stu2 := student{"name","class",18,100}
//直接初始化结构体拿到对应的指针
stu3 := &student{"name","class",18,100}/<code>
- 结构体的实例化4,通过构造函数
<code>stu4 := newStudent("name","class",18)/<code>
结构体的匿名字段,同种类型的字段只允许有一个,局限性很大
<code>type student2 struct {
string
int
}
var stu5 student2
stu5.string="string"
stu5.int=19/<code>
匿名结构体一般用在临时场景
<code>teacher := struct {
name string
age int
}{
//声明匿名结构体的同时进行初始化
name:"name",
age : 19,
}
//也可以按需更改字段的值
teacher.age=35/<code>
嵌套结构体的使用介绍
<code>type student struct {
name string
class string
age int
score int}
type collegeStudent struct {
major string
gfName string
stu student
}/<code>
<code>college := collegeStudent{
major: "major",
gfName: "gfName",
stu: student{
name: "name",
class: "class",
age: 28,
score: 90,
},
}
fmt.Println(college.gfName,college.stu.name)//gfName name/<code>
嵌套匿名结构体的使用场景
<code>type student struct {
name string
class string
age int
score int
}
type collegeStu struct {
major string
gfName string
student//注意没有给student起变量名
}/<code>
<code>college1 := collegeStu{
major: "major",
student: student{
name: "name",
}
,}
fmt.Println(college1.major)//这个毋庸置疑
//对于匿名结构体的取值,直接使用其类型名作为变量名
fmt.Println(college1.student.name)
//上面可以简写成这样
fmt.Println(college1.name)/<code>
总结:结构体的字段取值顺序,先在结构体本身找,如果本身没有这个字段,就去其嵌套的匿名结构体中找。在GO语言中是没有继承这个概念,而是叫做组合,通过组合匿名结构体来实现继承。
二、结构体的方法
构造体的方法简单介绍,格式如下
func (r receiveType)methodName(param paramType){
methodBody......
}
<code>func (s student)getSuffixName(suffix string)string{
return s.name + suffix
}/<code>
<code>fmt.Println(student{name: "小明", }.getSuffixName("好")) //小明好/<code>
修改接收者的值以及接收者copy副本代价较大时需用用指针接收者
<code>func (s *student)addAge(add int){
s.age += add
}/<code>
<code>s := student{ age: 18, }
s.addAge(1)
fmt.Println(s.age)/<code>
在GO语言中,不仅仅是结构体,可以为任意类型添加方法,当然指的本地类型,不是别人定义的包。
三、结构体的tag标签
结构体的tag标签的简单介绍
type myType struct {
fieldName fieldType `tagName:"tagValue"`
fieldName fieldType `tagName:"tagValue"`
...
}
<code>bytes, err := json.Marshal(struct { major string
gfName string}{"major", "gfName"})if ok==nil { fmt.Println(string(bytes)) //因为collegeStu字段都是小写代表私有,所以输出的结果是{}/<code>
结构体字段的可见性,如果字段是小写开头,则表示只能在本地包中访问,如果是大写,则表示可以公开访问(public),下面的这个字段大写,可以得到正常的json数据。
<code>bytes, err := json.Marshal(struct {
Major string
GfName string
}{"Major", "GfName"})
if err==nil{
fmt.Println(string(bytes))
}else{
fmt.Println(err)}
//{"Major":"Major","GfName":"GfName"}/<code>
可以看到得到的json串,很不正规(开头大写),这个时候tag就上场了,可以通过tag标签为json串的字段指定别名如下:
<code>bytes, err = json.Marshal(struct {
Major string `json:"major"`
GfName string `json:"gf_name"`}
{"Major", "GfName"})
if err==nil{
fmt.Println(string(bytes))
}else{
fmt.Println(err)
}
//{"major":"Major","gf_name":"GfName"}/<code>
同样的类似于的tag还有db form binding等。
让我们一起进步学习,共同成长;欢迎大家关注微信公众号:芝麻技术栈
閱讀更多 芝麻技術棧 的文章
關鍵字: Go语言