go语言基础之结构体

结构体
Go语言中的基础数据类型可以表示一些事物的基本属性,但是当我们想表达一个事物的全部或部分属性时,这时候再用单一的基本数据类型明显就无法满足需求了,Go语言提供了一种自定义数据类型,可以封装多个基本数据类型,这种数据类型叫结构体,英文名称struct。 也就是我们可以通过struct来定义自己的类型了。

package main

import "fmt"

func main() {
    //结构体的定义
    type person struct {
        name        string
        age, height int
        hobby       []string
    }
    //就够提的实例化
    var p1 person
    fmt.Println(p1)
    //结构体的初始化
    var p = person{
        name:   "董立群",
        age:    21,
        height: 175,
        hobby:  []string{"吃", "喝", "玩", "乐"},
    }
    fmt.Println(p)
    //结构体取值
    fmt.Println(p.name)
    fmt.Println(p.age)
    fmt.Println(p.hobby)
    //匿名结构体
    var structpp struct {
        name string
    }
    structpp.name = "郑凯健"
    fmt.Println(structpp)
    //指针结构体
    var ppp = new(person)
    ppp.name = "郭磊"
    fmt.Println(ppp)
    //go语言支持对指针结构体使用.来访问结构体的成员
    fmt.Println(ppp.name)
    //结构体的内存布局,结构体占用的是一块连续的内存
    type test struct {
        a int8
        b int8
        c int8
        d int8
    }
    n := test{
        1, 2, 3, 4,
    }
    fmt.Printf("n.a %p\n", &n.a)
    fmt.Printf("n.b %p\n", &n.b)
    fmt.Printf("n.c %p\n", &n.c)
    fmt.Printf("n.d %p\n", &n.d)
    //面试题
    type student struct {
        name string
        age  int
    }
    m := make(map[string]*student)
    stus := []student{
        {name: "小王子", age: 18},
        {name: "娜扎", age: 23},
        {name: "大王八", age: 9000},
    }
    //在这里,因为range是值拷贝,每一次循环都用的是stu这个变量,所以他的内存地址一直都没有变
    //也就是说最后stu中剩下的只有数组遍历的最后一个拷贝“大王八”。m的每个值都是指向stu的内存地址
    for _, stu := range stus {
        m[stu.name] = &stu
    }
    fmt.Println(m)
    for k, v := range m {
        fmt.Println(k, "=>", v.name)
    }
}

方法和接受者
Go语言中的方法(Method)是一种作用于特定类型变量的函数。这种特定类型变量叫做接收者(Receiver)。接收者的概念就类似于其他语言中的this或者 self。
指针接接收者
指针类型的接收者由一个结构体的指针组成,由于指针的特性,调用方法时修改接收者指针的任意成员变量,在方法结束后,修改都是有效的。这种方式就十分接近于其他语言中面向对象中的this或者self。 例如我们为Person添加一个SetAge方法,来修改实例变量的年龄。

package main

import "fmt"
type person struct {
    name string
    age  int
}
//方法的定义格式
// func (接收者变量 接收者类型) 方法名(参数列表) (返回参数) {
//     函数体
// }
func (p *person) fun() {
    p.name = "dlq"
    fmt.Println(p.name)
    p.newAge(3)
}
func (p *person) newAge(i int) {
    p.age = i
}
//给任意类型添加一个方法
type intt int
func (i intt) fu() {
}
func main() {
    var p = &person{}
    p.fun()
    fmt.Println(p.age)
    p.newAge(6)
    fmt.Println(p.age)
    //任意类型方法的调用
    var i = intt(1)
    i.fu()
    //匿名结构体
    type paa struct {
        int
        string
    }
    ppp := paa{
        23,
        "dlq",
    }
    fmt.Println(ppp)
    //结构体的嵌套
    //匿名结构体嵌套的情况下,不用先调用paa结构体再调用paa中的值,可以直接通过p1调用
    //在结构体嵌套中,如果出现了嵌套结构体名字重复,那么就要指定具体的内嵌结构体字段名。
    type person0 struct {
        name string
        age  int
        paa
    }
    var p1 = person0{
        "dlq",
        23,
        paa{
            23,
            "dlq",
        },
    }
    fmt.Println(p1.name)
    fmt.Println(p1)
}

结构体模拟继承

package main

type person struct {
    name string
    age  int
}
type dog struct {
    name string
    age  int
    person
}
func (p *person) fun() {
}
func (d *dog) funcc() {
}
func main() {
    d := &dog{}
    d.funcc()
    d.fun()
}

结构体与json序列化

package main

import (
    "encoding/json"
    "fmt"
)
type person struct {
    Name string `json:"name"`
    Age  int    `json:"age"`
}
type person1 struct {
    Name string `json:"name"`
    Age  int    `json:"age"`
}

func main() {
    p := &person{
        "dlq",
        32,
    }
    //序列化
    jss, err := json.Marshal(p)
    if err != nil {
        fmt.Println("error")
        return
    }
    fmt.Println(string(jss))
    //反序列化
    p1 := &person1{}
    str := `{"name":"dlq","age":23}`
    err1 := json.Unmarshal([]byte(str), p1)
    if err1 != nil {
        fmt.Println("error")
        return
    }
    fmt.Println(p1)
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值