add golang note

This commit is contained in:
gameloader 2022-11-09 15:57:51 +08:00
parent 379950bba2
commit 6ceb74bfa6

View File

@ -0,0 +1,76 @@
---
title: golang后端开发笔记
author: Logic
date: 2022-11-08
categories: ["开发"]
draft: false
tags: []
---
1. [golang语言问题](#golang语言问题)
* [slice传参](#slice传参)
* [修改slice中struct的问题](#修改slice中struct的问题)
# golang后端开发笔记
之前的小程序使用的是原生的云开发方便固然方便但实际上并没有做太多的工作也不需要考虑过多的问题这次用golang重写后端算是对自身的一个挑战从头梳理后端开发的基本内容并且深入理解golang语言和网络相关的知识。
主要使用gin+gorm+Mysql+Redis
## golang语言问题
### slice传参
### 修改slice中struct的问题
在修改slice中的数据时自然会想到用for range循环。但在实际使用的过程中需要注意golang语言中range循环的一些特性。下面给出一个例子
```go
func main() {
slice := []int{10, 20, 30, 40}
for index, value := range slice {
fmt.Printf("value = %d , value-addr = %x , slice-addr = %x\n", value, &value, &slice[index])
}
}
```
这里value如果代表的是slice切片中的各个数据那么value的地址理应随着循环发生变化但是实际上输出的结果为
> value = 10 , value-addr = c4200aedf8 , slice-addr = c4200b0320
>
> value = 20 , value-addr = c4200aedf8 , slice-addr = c4200b0328
>
> value = 30 , value-addr = c4200aedf8 , slice-addr = c4200b0330
>
> value = 40 , value-addr = c4200aedf8 , slice-addr = c4200b0338
显然value的地址并没有发生变化这说明value本身是一个结构在循环过程中只是将对应的值拷贝到了value当中value并不是指向切片中对应值的指针。
关于这点在golang的官方wiki中的CommonMistakes中给出了相关的说明官方给出的例子如下
```go
func main() {
var out []*int
for i := 0; i < 3; i++ {
out = append(out, &i)
}
fmt.Println("Values:", *out[0], *out[1], *out[2])
fmt.Println("Addresses:", out[0], out[1], out[2])
}
```
官方给出的例子也非常有趣,这个例子实际上的输出结果为
> Values: 3 3 3
>
> Addresses: 0x40e020 0x40e020 0x40e020
在Go中循环过程中的循环迭代器如第二个例子中的i以及第一个例子中的value都是一个单独的变量在循环进行过程中会将不同的值拷贝给这个变量这样的好处在于只需要为这个变量申请一次内存空间之后改变它的值就可以了。但是因为只是将不同的值赋给这一个变量该变量的地址一直没有变化这时我们将该变量的地址放入out切片中则最后通过解引用取得的值是该变量最后一次被赋予的值。即循环过程可以理解为
```go
func main(){
var new_variable int
var out []*int
// 模拟循环的过程
new_variable = 1
append(out, &new_variable)
new_variable = 2
append(out, &new_variable)
new_variable = 3
append(out, &new_variable)
}
```
这样一来这个循环最后的结果就很容易理解了。这个问题看似是一个小问题但在实际编写程序的过程中常常会因疏忽这个问题而出错比如在遍历一个结构体切片时赋值给迭代器的成员变量循环结束后会发现结构体切片中的值并没有改变实际上应该使用诸如out[i]这种通过下标访问的形式修改切片中的值,而不是使用迭代器。这点要时刻注意