Go基础:基础语法与使用

这是我参与「第三届青训营 -后端场」笔记创作活动的的第1篇笔记。

1. 变量

声明变量

var a int
var b string
var c []float32
// 这种形式一般用于回调函数,即将函数以变量的形式保存下来,在需要的时候重新调用这个函数
var d func() bool
var e struct{
           x int }

批量格式

var (
    a int
    b string
    c []float32
    d func() bool
    e struct {
        x int
    }
)

2. 指针

指针概念在Go语言中被拆分为两个核心概念:

  • 类型指针,允许对这个指针类型的数据进行修改。传递数据使用指针,而无须拷贝数据。类型指针不能进行偏移和运算。
  • 切片,由指向起始元素的原始指针、元素数量和容量组成。

受益于这样的约束和拆分,Go语言的指针类型变量拥有指针的高效访问,但又不会发生指针偏移,从而避免非法修改关键性数据问题。同时,垃圾回收也比较容易对不会发生偏移的指针进行检索和回收。

var cat int = 1
var str string = "banana"
fmt.Printf("%p %p", &cat, &str)
//0xc042052088 0xc0420461b0

输出值在每次运行是不同的,代表cat和str两个变量在运行时的地址。
在32位平台上,将是32位地址;64位平台上是64位地址。

// 交换函数
func swap(a, b *int) {
  // 取a指针的值,赋给临时变量t
   t := *a
  // 取b指针的值,赋给a指针指向的变量
  *a = *b
  // 将a指针的值赋给b指针指向的变量
    *b = t
}

func main() {
// 准备两个变量,赋值1和2
    x, y := 1, 2
  // 交换变量值
   swap(&x, &y)
  // 输出变量值
   fmt.Println(x, y)
}

使用指针变量获取命令行的输入信息

Go语言的flag包中,定义的指令以指针类型返回

// 定义命令行参数
var mode = flag.String("mode", "", "process mode")
	func main() {
	// 解析命令行参数
	flag.Parse()
	// 输出命令行参数
	fmt.Println(*mode)
}

$ go run flagparse.go --mode=fast

  • 参数名称:给应用输入参数时使用
    参数值的默认值:与flag所使用的函数创建变量类型对应,String对应字符串、Int对应整型、Bool对应布尔型等。
  • 参数说明:使用-help时,会出现在说明中。

在这里插入图片描述

创建指针的另一种方法——new()函数

str := new(string)
*str = "ninja"

变量生命期——变量能够使用的代码范围

变量和栈有什么关系?

func calc(a, b int) int {
	var c int
	c = a * b
	var x int
	x = c * 10
	return x
}

栈可用于内存分配,栈的分配和回收速度非常快。Go语言默认情况下会将c和x分配在栈上,这两个变量在calc()函数退出时就不再使用,函数结束时,保存c和x的栈内存再出栈释放内存,

什么是堆?
堆在内存分配中类似于往一个房间里摆放各种家具,家具的尺寸有大有小。分配内存时,需要找一块足够装下家具的空间再摆放家具。经过反复摆放和腾空家具后,房间里的空间会变得乱七八糟,此时再往空间里摆放家具会存在虽然有足够的空间,但各空间分布在不同的区域,无法有一段连续的空间来摆放家具的问题。此时,内存分配器就需要对这些空间进行调整优化。

堆分配内存和栈分配内存相比,堆适合不可预知大小的内存分配。但是为此付出的代价是分配速度较慢,而且会形成内存碎片。

3. 字符串

长度

  • ASCII字符串长度使用 len() 函数。
  • Unicode字符串长度使用 utf8.RuneCountInString() 函数。

遍历字符串

  • ASCII字符串遍历直接使用下标。
  • Unicode字符串遍历用 for range

修改字符串

  • Go语言的字符串是不可变的
  • 修改字符串时,可以将字符串转换为 []byte 进行修改。
  • []bytestring 可以通过强制类型转换互转

连接字符串

使用“+”对字符串进行连接操作,但在频繁拼接字符串的场景“+”性能低效。除了加号连接字符串,Go语言中也有类似于StringBuilder的机制来进行高效的字符串连接:

hammer := "吃我一锤"
sickle := "死吧"
// 声明字节缓冲
var stringBuilder bytes.Buffer
// 把字符串写入缓冲
stringBuilder.WriteString(hammer)
stringBuilder.WriteString(sickle)
// 将缓冲以字符串形式输出
fmt.Println(stringBuilder.String())
// bytes.Buffer是可以缓冲并可以往里面写入各种字节数组的。字符串也是一种字节数组,使用WriteString()方法进行写入。
// 将需要连接的字符串,通过调用WriteString()方法,写入stringBuilder中,然后再通过stringBuilder.String()方法将缓冲转换为字符串。

格式化

fmt.Sprintf(格式化样式,参数列表…)

  • 格式化样式:字符串形式,格式化动词以%开头。
  • 参数列表:多个参数以逗号分隔,个数必须与格式化样式中的个数一一对应,否则运行时会报错。
    在这里插入图片描述

posted on 2022-05-14 15:23  micromatrix  阅读(65)  评论(0编辑  收藏  举报

导航