Go基础:指针、Map、结构体

简介: Go基础:指针、Map、结构体

 Map

Go语言中的map是引用类型,必须初始化才能使用,是一种无序的基于key-value的数据结构

func main() {
    scoreMap := make(map[string]int, 8)
    scoreMap["张三"] = 90
    scoreMap["小明"] = 100
    fmt.Println(scoreMap)
    fmt.Println(scoreMap["小明"])
    fmt.Printf("type of a:%T\n", scoreMap)
}

image.gif


image.gif

Go语言中使用for range遍历map

func main() {
    scoreMap := make(map[string]int)
    scoreMap["张三"] = 90
    scoreMap["小明"] = 100
    scoreMap["王五"] = 60
    for k, v := range scoreMap {
        fmt.Println(k, v)
    }
}

image.gif


image.gif

按照指定顺序遍历map

func main() {
    rand.Seed(time.Now().UnixNano()) //初始化随机数种子
    var scoreMap = make(map[string]int, 200)
    for i := 0; i < 100; i++ {
        key := fmt.Sprintf("stu%02d", i) //生成stu开头的字符串
        value := rand.Intn(100)          //生成0~99的随机整数
        scoreMap[key] = value
    }
    //取出map中的所有key存入切片keys
    var keys = make([]string, 0, 200)
    for key := range scoreMap {
        keys = append(keys, key)
    }
    //对切片进行排序
    sort.Strings(keys)
    //按照排序后的key遍历map
    for _, key := range keys {
        fmt.Println(key, scoreMap[key])
    }
}

image.gif


image.gif

元素为map类型的切片

func main() {
    var mapSlice = make([]map[string]string, 3)
    for index, value := range mapSlice {
        fmt.Printf("index:%d value:%v\n", index, value)
    }
    fmt.Println("after init")
    // 对切片中的map元素进行初始化
    mapSlice[0] = make(map[string]string, 10)
    mapSlice[0]["name"] = "王五"
    mapSlice[0]["password"] = "123456"
    mapSlice[0]["address"] = "红旗大街"
    for index, value := range mapSlice {
        fmt.Printf("index:%d value:%v\n", index, value)
    }
}

image.gif

值为切片类型的map

func main() {
    var sliceMap = make(map[string][]string, 3)
    fmt.Println(sliceMap)
    fmt.Println("after init")
    key := "中国"
    value, ok := sliceMap[key]
    if !ok {
        value = make([]string, 0, 2)
    }
    value = append(value, "北京", "上海")
    sliceMap[key] = value
    fmt.Println(sliceMap)
}

image.gif

结构体

Go语言中没有“类”的概念,也不支持“类”的继承等面向对象的概念

Go语言中通过结构体的内嵌再配合接口比面向对象具有更高的扩展性和灵活性。

类型定义和类型别名的区别

类型别名与类型定义表面上看只有一个等号的差异

//类型定义
type NewInt int
//类型别名
type MyInt = int
func main() {
    var a NewInt
    var b MyInt
    fmt.Printf("type of a:%T\n", a) //type of a:main.NewInt
    fmt.Printf("type of b:%T\n", b) //type of b:int
}

image.gif

struct

Go语言中通过struct来实现面向对象


image.gif

取结构体的地址

type student struct {
    name string
    age  int
}
func main() {
    m := make(map[string]*student)
    stus := []student{
        {name: "pprof.cn", age: 18},
        {name: "测试", age: 23},
        {name: "博客", age: 28},
    }
    for _, stu := range stus {
        m[stu.name] = &stu
    }
    for k, v := range m {
        fmt.Println(k, "=>", v.name)
    }
}

image.gif

结构体没有构造函数,可自己实现

Go语言的结构体没有构造函数,我们可以自己实现。 例如,下方的代码就实现了一个person的构造函数。 因为struct是值类型,如果结构体比较复杂的话,值拷贝性能开销会比较大,所以该构造函数返回的是结构体指针类型

image.gif

func newPerson(name, city string, age int8) *person {
    return &person{
        name: name,
        city: city,
        age:  age,
    }
}

image.gif

调用构造函数

p9 := newPerson("pprof.cn", "测试", 90)
fmt.Printf("%#v\n", p9)

image.gif

方法和接收者

Go语言中的方法(Method)是一种作用于特定类型变量的函数。这种特定类型变量叫做接收者(Receiver)。接收者的概念就类似于其他语言中的this或者 self。

image.gif

方法的定义格式如下:

func (接收者变量 接收者类型) 方法名(参数列表) (返回参数) {
        函数体
    }

image.gif

其中,

    • 接收者变量:接收者中的参数变量名在命名时,官方建议使用接收者类型名的第一个小写字母,而不是self、this之类的命名。例 如,Person类型的接收者变量应该命名为 p,Connector类型的接收者变量应该命名为c等。
    • 接收者类型:接收者类型和参数类似,可以是指针类型和非指针类型。
    • 方法名、参数列表、返回参数:具体格式与函数定义相同。

    举个例子:

    //Person 结构体
    type Person struct {
        name string
        age  int8
    }
    //NewPerson 构造函数
    func NewPerson(name string, age int8) *Person {
        return &Person{
            name: name,
            age:  age,
        }
    }
    //Dream Person做梦的方法
    func (p Person) Dream() {
        fmt.Printf("%s的梦想是学好Go语言!\n", p.name)
    }
    func main() {
        p1 := NewPerson("测试", 25)
        p1.Dream()
    }

    image.gif

    方法与函数的区别是,函数不属于任何类型,方法属于特定的类型。

    image.gif

    值接收者  VS 指针接收者

    image.gif

      • 值接收者 是go语言特有
      • 值/指针接收者均可接收值/指针

      结构体的“继承”

      Go语言中使用结构体也可以实现其他编程语言中面向对象的继承。

      //Animal 动物
      type Animal struct {
          name string
      }
      func (a *Animal) move() {
          fmt.Printf("%s会动!\n", a.name)
      }
      //Dog 狗
      type Dog struct {
          Feet    int8
          *Animal //通过嵌套匿名结构体实现继承
      }
      func (d *Dog) wang() {
          fmt.Printf("%s会汪汪汪~\n", d.name)
      }
      func main() {
          d1 := &Dog{
              Feet: 4,
              Animal: &Animal{ //注意嵌套的是结构体指针
                  name: "乐乐",
              },
          }
          d1.wang() //乐乐会汪汪汪~
          d1.move() //乐乐会动!
      }

      image.gif

      封装:结构体字段的可见性

      image.gif

      结构体中字段大写开头表示可公开访问小写表示私有(仅在定义当前结构体的包中可访问)。

        • 每个目录一个包
        • main包包含可执行入口
        • 为结构定义的方法必须放在同一个包内
        • 可以是不同文件

        如何库充系统类型或者别人的类型

          • 定义别名
          • 使用组合

          image.gif

          参考链接:

          结构体 · Go语言中文文档


          目录
          相关文章
          |
          2月前
          |
          Go
          go语言中遍历映射(map)
          go语言中遍历映射(map)
          55 8
          |
          29天前
          |
          程序员 Go
          go语言中结构体(Struct)
          go语言中结构体(Struct)
          101 71
          |
          1月前
          |
          Go
          go语言for遍历映射(map)
          go语言for遍历映射(map)
          35 12
          |
          2月前
          |
          存储 C语言
          C语言如何使用结构体和指针来操作动态分配的内存
          在C语言中,通过定义结构体并使用指向该结构体的指针,可以对动态分配的内存进行操作。首先利用 `malloc` 或 `calloc` 分配内存,然后通过指针访问和修改结构体成员,最后用 `free` 释放内存,实现资源的有效管理。
          154 13
          |
          2月前
          |
          存储 Rust Go
          Go nil 空结构体 空接口有什么区别?
          本文介绍了Go语言中的`nil`、空结构体和空接口的区别。`nil`是预定义的零值变量,适用于指针、管道等类型;空结构体大小为0,多个空结构体实例指向同一地址;空接口由`_type`和`data`字段组成,仅当两者均为`nil`时,空接口才为`nil`。
          Go nil 空结构体 空接口有什么区别?
          |
          2月前
          |
          存储 Go
          go语言 遍历映射(map)
          go语言 遍历映射(map)
          38 2
          |
          2月前
          |
          编译器 Go
          探索 Go 语言中的内存对齐:为什么结构体大小会有所不同?
          在 Go 语言中,内存对齐是优化内存访问速度的重要概念。通过调整数据在内存中的位置,编译器确保不同类型的数据能够高效访问。本文通过示例代码展示了两个结构体 `A` 和 `B`,尽管字段相同但排列不同,导致内存占用分别为 40 字节和 48 字节。通过分析内存布局,解释了内存对齐的原因,并提供了优化结构体字段顺序的方法,以减少内存填充,提高性能。
          45 3
          |
          2月前
          |
          存储 人工智能 算法
          数据结构实验之C 语言的函数数组指针结构体知识
          本实验旨在复习C语言中的函数、数组、指针、结构体与共用体等核心概念,并通过具体编程任务加深理解。任务包括输出100以内所有素数、逆序排列一维数组、查找二维数组中的鞍点、利用指针输出二维数组元素,以及使用结构体和共用体处理教师与学生信息。每个任务不仅强化了基本语法的应用,还涉及到了算法逻辑的设计与优化。实验结果显示,学生能够有效掌握并运用这些知识完成指定任务。
          60 4
          |
          4月前
          |
          Go
          Go to Learn Go之结构体
          Go to Learn Go之结构体
          44 5
          |
          4月前
          |
          Go 定位技术 索引
          Go 语言Map(集合) | 19
          Go 语言Map(集合) | 19