package main
import (
"encoding/json"
"fmt"
)
// 标题: 结构体
type myInt int32 // 自定义一个myint类型, 实际是int32
type intAlias = int64 // 类型别名
func customTypeTest() {
fmt.Printf("%T\n", myInt(100)) // 输出main.myInt
fmt.Printf("%T\n", intAlias(100)) // 输出int64
fmt.Printf("%T\n", rune('中')) // 输出int32
}
// 定义person结构体. 结构体是值类型
type person struct {
name string
age int32
}
func personTest() {
// 通过字段赋值生成变量
var zf person
zf.name = "张飞"
zf.age = 100
fmt.Printf("%T\t%v\n", zf, zf) // 输出main.person {张飞 100}
fmt.Printf("%#v\n", zf) // 输出main.person{name:"张飞", age:100}
}
// 匿名结构体
func anonymousStructTest() {
var zf struct {
name string
age int32
}
fmt.Printf("%#v\n", zf) // 输出struct { name string; age int32 }{name:"", age:0}
}
// 结构体指针
func structPointerTest() {
p := new(person)
p.name = "张三" // 不是*p.name="张三"
p.age = 13 // 也不是p->name="张三"
// 对指针用%v会取值
fmt.Printf("%v", p) // 输出&{张三 13}
}
// 结构体初始化赋值
func structInitTest() {
var p1 = person{ // 用词典初始化
name: "张三",
age: 10, // 最后一行必须带逗号
}
fmt.Println(p1)
var p2 = person{ // 按列表初始化
"张三",
0, // 最后一行必须带逗号
}
fmt.Println(p2)
var p3 = &person{ // 结构体指针的初始化
"张三",
0,
}
fmt.Println(p3)
}
// 构造函数是返回结构体对象的函数
func newPerson(name string, age int32) *person {
return &person{
name: name,
age: age,
}
}
// 结构体的成员函数, 函数名字左边的是接收者.
// 下面的例子是值接收者.
// 类名和函数名, 如果首字母是大写, 就有公有(可以被别的包调用), 否则就是私有
// 公有类和函数必须有注释
func (p person) printName() {
println(p.name)
}
func printNameTest() {
p := newPerson("张三", 13)
p.printName()
}
// 值接收者会有结构体拷贝过程. 指针接收者就没有, 例子如下
func (p *person) printAge() {
p.age++
println(p.age)
}
func printAgeTest() {
p := newPerson("张三", 13)
p.printAge()
print(p.age)
}
// 只能给本包的自定义类型添加方法
func (m myInt) printMyInt() {
println("printMyInt:", m)
}
func printMyIntTest() {
m := myInt(5)
m.printMyInt()
}
// 匿名字段
// 成员名可以省略, 直接用类型名访问
type dog struct {
int
string
}
func dogTest() {
d := dog{
int: 0,
string: "12",
}
fmt.Println(d.int)
}
// 结构体嵌套
type cat struct {
nick string
year int
person
}
func catTest() {
c := cat{
nick: "小白",
year: 5,
person: person{
name: "张飞",
age: 40,
},
}
fmt.Println(c) // 输出 {小白 5 {张飞 40}}
fmt.Println(c.person.name) // 输出 张飞
// 匿名字段+结构体嵌套可以直接访问person中的变量
// 使用匿名结构体嵌套要防止字段冲突
fmt.Println(c.name) // 输出 张飞
}
// 通过结构体嵌套模拟"继承"
func (p person) work() {
fmt.Printf("%s正在工作\n", p.name)
}
func simulateExtension() {
c := cat{
nick: "小白",
year: 5,
person: person{
name: "张飞",
age: 40,
},
}
// 可以直接访问匿名嵌套结构体字段的方法
c.work() // 输出 张飞正在工作
}
// 结构体转换成JSon
type Person struct { // 要先定义一个公有结构体
Name string `json:"name"` // 大写字母开头是公有
Age int `json:"age"` // 因为要被外面的json包访问
}
func structToJson() {
p := Person{
Name: "张飞",
Age: 40,
}
str, err := json.Marshal(p)
if err != nil {
fmt.Println(err)
} else {
fmt.Println(string(str)) // 输出 {"name":"张飞","age":40}
fmt.Printf("%#v\n", string(str)) // 输出 "{\"name\":\"张飞\",\"age\":40}"
}
}
// JSon转换成结构体
func jsonToStruct() {
str := `{"Name":"张飞","Age":40}`
var p Person
err := json.Unmarshal([]byte(str), &p)
if err != nil {
fmt.Println(err)
} else {
fmt.Printf("%#v", p) // 输出 main.Person{Name:"张飞", Age:40}
}
}
Go语言学习草稿(5) 结构体
最新推荐文章于 2024-04-10 20:23:51 发布