struct中的tag
我们可以为struct中的每个字段,写上一个tag。这个tag可以通过反射的
机制获取到,最常用的场景就是json序列化和反序列化
package main
import "fmt"
import "encoding/json"
type student struct {
Name string `json:"stu_name"`
Age int
}
func main() {
var stu student = student{
Name:"safly",
Age:10,
}
data,err := json.Marshal(stu)
if err != nil{
fmt.Println("json encode stu failed",err)
return
}
fmt.Println(string(data))
}
输出如下:
PS E:\golang\go_pro\src\safly> go run demo.go
{"stu_name":"safly","Age":10}
PS E:\golang\go_pro\src\safly>
匿名字段
结构体中字段可以没有名字,即匿名字段
package main
import (
"fmt"
)
type student struct {
name string
age int
}
type stu struct{
student
int
}
func main() {
var stu1 stu
stu1.name = "saly"
stu1.age =10
stu1.int = 100
fmt.Println(stu1)
fmt.Println("---------------------")
var stu2 stu
stu2.name = "salyyy"
stu2.age =100
stu2.int = 1000
//都设置age name时候,就看自己的
stu2.student.name = "ss"
stu2.student.age = 11
fmt.Println(stu2)
}
输出如下:
PS E:\golang\go_pro\src\safly> go run demo.go
{{saly 10} 100}
---------------------
{{ss 11} 1000}
PS E:\golang\go_pro\src\safly>
方法
方法作用在结构体上
Golang中的方法是作用在特定类型的变量上,因此自定义类型,都可以
有方法,而不仅仅是struct
定义:func (recevier type) methodName(参数列表)(返回值列表){}
package main
import (
"fmt"
)
type Student struct {
Name string
Age int
Score int
}
/*结构体方法*/
func (p Student) init(name string,age int ,score int){
p.Name = name
p.Age = age
p.Score = score
fmt.Println(p)
}
func (p Student)get() Student{
return p
}
func main() {
var stu Student
stu.init("safly",1,1)
stu1 := stu.get()
fmt.Println(stu1)
fmt.Println(stu)
}
输出如下:
PS E:\golang\go_pro\src\safly> go run demo.go
{safly 1 1}
{ 0 0}
{ 0 0}
PS E:\golang\go_pro\src\safly>
我们发现上例中init方法没有修改对象的值,我们接下来修改下代码如下:
/*结构体方法*/
func (p *Student) init(name string,age int ,score int){
p.Name = name
p.Age = age
p.Score = score
fmt.Println(p)
}
看看输出结果:
PS E:\golang\go_pro\src\safly> go run demo.go
&{safly 1 1}
{safly 1 1}
{safly 1 1}
PS E:\golang\go_pro\src\safly>
当然我们还可以在上例修改的基础上,在此修改如下代码
var stu Student
(&stu).init("safly",1,1)
stu1 := stu.get()
fmt.Println(stu1)
fmt.Println(stu)
结果输出如下:
PS E:\golang\go_pro\src\safly> go run demo.go
&{safly 1 1}
{safly 1 1}
{safly 1 1}
PS E:\golang\go_pro\src\safly>
方法作用在其他变量上
我们看下讲方法作用在其他的变量类型上
package main
import (
"fmt"
)
type mInt int
func (p mInt)onInt(){
fmt.Println("p is",p)
}
func (p *mInt)set(b mInt){
*p = b
}
func main() {
var a mInt =100
fmt.Println(a)
a.onInt()
//&a是传递内存地址值,当时如果传a
//go会自动转换成内存地址来看待所以都是可以的
a.set(200)
(&a).set(200)
fmt.Println(a)
}
输出如下:
PS E:\golang\go_pro\src\safly> go run demo.go
100
p is 100
200
PS E:\golang\go_pro\src\safly>
继承
如果一个struct嵌套了另一个匿名结构体,那么这个结构可以直接访问
匿名结构体的方法,从而实现了继承。
package main
import (
"fmt"
)
type Car struct{
weight int
name string
}
func (p *Car)Run(){
fmt.Println("running")
}
/*继承Car*/
type Bike struct{
Car
lunzi int
}
/*继承Car*/
type Train struct{
Car
}
func main() {
var bike Bike
bike.weight = 100
bike.name = "bike"
bike.lunzi = 4
fmt.Println(bike)
bike.Run()
fmt.Println("-------")
var train Train
train.weight = 111
train.name = "train"
fmt.Println(train)
train.Run()
}
输出如下:
PS E:\golang\go_pro\src\safly> go run demo.go
{{100 bike} 4}
running
-------
{{111 train}}
running
PS E:\golang\go_pro\src\safly>
String
如果一个变量实现了String()这个方法,那么fmt.Println默认会调用这个
变量的String()进行输出。
package main
import (
"fmt"
)
type Car struct{
weight int
name string
}
func (p *Car)Run(){
fmt.Println("running")
}
/*继承Car*/
type Train struct{
Car
}
/*
如果一个变量实现了String()这个方法,
那么fmt.Println默认会调用这个
变量的String()进行输出。
*/
func (t *Train)String() string{
str:= fmt.Sprintf("name=%s weight=%d",(*t).name,(*t).weight)
return str
}
func main() {
var train Train
train.weight = 1111
train.name = "train"
fmt.Println(train)
train.Run()
fmt.Printf("%s",&train)
}
输出如下:
PS E:\golang\go_pro\src\safly> go run demo.go
{{1111 train}}
running
name=train weight=1111
PS E:\golang\go_pro\src\safly>