mirror of
https://gitlab.com/game-loader/hugo.git
synced 2025-04-20 14:02:07 +08:00
add golang note
This commit is contained in:
parent
379950bba2
commit
6ceb74bfa6
76
content/posts/golang_backend.md
Normal file
76
content/posts/golang_backend.md
Normal 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]这种通过下标访问的形式修改切片中的值,而不是使用迭代器。这点要时刻注意
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user