GO语言基础知识(四)结构体和方法(不断更新)

一、类型和结构体

基于已有类型(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等。


让我们一起进步学习,共同成长;欢迎大家关注微信公众号:芝麻技术栈


分享到:


相關文章: