运维八一 运维八一
首页
运维杂记
编程浅尝
周积跬步
专栏
生活
关于
收藏
  • 分类
  • 标签
  • 归档
Source (opens new window)

运维八一

运维,运维!
首页
运维杂记
编程浅尝
周积跬步
专栏
生活
关于
收藏
  • 分类
  • 标签
  • 归档
Source (opens new window)
  • Go

    • 前言

    • Go基础知识

    • Go基本语法

    • 实战项目:简单web服务

    • 基本数据类型

      • 内置类型
      • 内置函数
      • 数字 int
      • 布尔值 bool
      • 字符串 string
      • 数组 array
      • 切片 sice
      • 字典 map
      • 指针
        • 9. 指针
          • 9.1 关于指针
          • 9.2 &取变量地址
          • 9.3 new和make
          • 9.3.1 make和new比较
          • 9.3.2 new函数
          • 9.3.3 make函数
    • 内置运算符

    • 分支和循环

    • 函数 function

    • 结构体 struct

    • 方法 method

    • 实战项目:跟踪函数调用链

    • 接口 interface

    • 并发 concurrency

    • 指针

    • 实战项目:实现轻量级线程池

    • 实战项目:实现TCP服务器

    • go常用包

    • Gin框架

    • go随记

  • Python

  • Shell

  • Java

  • Vue

  • 前端

  • 编程浅尝
  • Go
  • 基本数据类型
lyndon
2022-06-07
目录

指针

# 9. 指针

# 9.1 关于指针

要搞明白 Go 语言中的指针需要先知道 3 个概念: ==指针地址、指针类型、指针取值==

  • 指针地址(&a)
  • 指针取值(*&a)
  • 指针类型(&a) —> *int 改变数据传指针

变量的本质是给存储数据的内存地址起了一个好记的别名。比如我们定义了一个变量 a := 10 ,这个时候可以直接通过 a 这个变量来读取内存中保存的 10 这个值。在计算机底层 a 这个变量其实对应了一个内存地址。指针也是一个变量,但它是一种特殊的变量,它存储的数据不是一个普通的值,而是另一个变量的内存地址。

Go 语言中的指针操作非常简单,我们只需要记住两个符号:&(取地址)和 *(根据地址取值)

image-20220329225653947

package main

import "fmt"

func main() {
   var a = 10
   fmt.Printf("%d \n", &a)  // &a 指针地址 (824633802904)
   fmt.Printf("%d \n", *&a) // *&a 指针取值 (10)
   fmt.Printf("%T \n", &a)  // %T 指针类型 (*int )
}
1
2
3
4
5
6
7
8
9
10

# 9.2 &取变量地址

&符号取地址操作

package main

import "fmt"

func main() {
   var a = 10
   var b = &a
   var c = *&a
   fmt.Println(a) // 10 a的值
   fmt.Println(b) // 0xc000014098 a变量的内存地址
   fmt.Println(c) // 10 *内存地址 取值
}
1
2
3
4
5
6
7
8
9
10
11
12

b := &a 图示:

image-20220329232604958

# 9.3 new和make

package main

import "fmt"

func main() {
   var userInfo map[string]string
   userInfo["username"] = "zhangsan"
   fmt.Println(userInfo)
}
/*
panic: assignment to entry in nil map
*/
1
2
3
4
5
6
7
8
9
10
11
12

执行上面的代码会引发 panic,为什么呢?

在 Go 语言中对于引用类型的变量,我们在使用的时候不仅要声明它,还要为它分配内存空间,否则我们的值就没办法存储。

而对于值类型的声明不需要分配内存空间,是因为它们在声明的时候已经默认分配好了内存空间。

要分配内存,就引出来今天的 new 和 make。Go 语言中 new 和 make 是内建的两个函数,主要用来分配内存。

# 9.3.1 make和new比较

make和new的区别:

  • make 关键字的作用是创建于 slice、map 和 channel 等内置的数据结构;
  • new 关键字的作用是为类型申请一片内存空间,并返回指向这片内存的指针。
package main

import "fmt"

func main() {
   a := make([]int, 3, 10) // 切片长度为 1,预留空间长度为 10
   a = append(a, 1)
   fmt.Printf("%v--%T \n", a, a) // [0 0 0 1]--[]int 值----切片本身

   var b = new([]int)
   // b = b.append(b,2)   // 返回的是内存指针,所以不能直接 append
   *b = append(*b, 2)            // 必须通过 * 指针取值,才能进行 append 添加
   fmt.Printf("%v--%T \n", b, b) // &[2]--*[]string 内存的指针---内存指针

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# 9.3.2 new函数

系统默认的数据类型,分配空间

package main

import "fmt"

func main() {
   // 1.new实例化int
   age := new(int)
   *age = 1
   fmt.Println(*age) // 1

   // 2. new实例化切片
   li := new([]int)
   *li = append(*li, 1)
   fmt.Println(*li) // [1]

   // 3. new实例化map
   userInfo := new(map[string]string)
   *userInfo = map[string]string{}
   (*userInfo)["username"] = "张三"
   fmt.Println(userInfo) // &map[username:张三]


}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

自定义类型使用 new 函数来分配空间

package main

import "fmt"

func main() {
   var s *Student
   s = new(Student)	//分配空间
   s.name = "zhangsan"
   fmt.Println(s)	// &{zhangsan 0}
}

type Student struct {
   name string
   age  int
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# 9.3.3 make函数

make 也是用于内存分配的,但是和 new 不同,它只用于 chan、map 以及 slice 的内存创建,而且它返回的类型就是这三个类型本身,而不是他们的指针类型,因为这三种类型就是引用类型,所以就没有必要返回他们的指针了。

package main

import "fmt"

func main() {
   a := make([]int, 3, 10) // 切片长度为 1,预留空间长度为 10
   b := make(map[string]string)
   c := make(chan int, 1)
   fmt.Println(a, b, c)   // [0 0 0] map[] 0xc0000180e0
}
1
2
3
4
5
6
7
8
9
10

当为slice分配内存的时候,应当尽量预估到slice可能的最大长度,通过给make传第三个参数的方式来给slice预留好内存空间,这样可以避免二次分配内存带来的开销,大大提高程序的性能。

上次更新: 2022/06/12, 15:48:09
字典 map
算数运算符

← 字典 map 算数运算符→

最近更新
01
ctr和crictl显示镜像不一致
03-13
02
alpine镜像集成常用数据库客户端
03-13
03
create-cluster
02-26
更多文章>
Theme by Vdoing | Copyright © 2015-2024 op81.com
苏ICP备18041258号-2
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式