作为一个5年的phper,这两年公司和个人都在顺应技术趋势,新项目慢慢从php转向了go语言,从2021年到现在,笔者手上也先后开发了两个go项目。在学习go语言的过程中也学习并总结了一些相关的东西,这篇文章就分享下自己踩过的一些坑吧。
问题:
func main()
{
fmt.Println("php是世界上最好的语言")
}
解决:
如上所示,这种函数的定义写法,在go语言中是错误的,就是 “{” 必须得和函数名在同一行。当然,这种错误在编辑器检测语法的时候就会暴露出来了,正确写法应该如下所示:
func main() {
fmt.Println("php是世界上最好的语言")
}
问题:
func main() {
var m map[string]string
m["php"] = "世界上最好的语言"
m["go"] = "世界上最好的语言"
fmt.Println(m)
}
解决:
如上所示,这种定义了map,然后直接使用的方式是错误的,会抛出一个panic。少了一个重要的步骤,必须使用make()函数去给map分配内存空间,才能使用。这个对于phper来说,刚开始可能会经常忘掉。正确使用方式如下:
func main() {
m := make(map[string]string, 2)
m["php"] = "世界上最好的语言"
m["go"] = "世界上最好的语言"
fmt.Println(m)
}
问题:
type Student struct {
id int
name string
score int
}
func main() {
s := Student{1, "小明", 99}
jsonS, _ := json.Marshal(s)
fmt.Println(string(jsonS))
}
解决:
在做web开发过程中,基本上每天都要和json格式数据打交道,所以学会转换成json格式的数据是必备技能啊。但上面的写法是错误的,打印出来的为空值。这是因为Student结构体中的元素都是小写的,对外是不可访问的,所以必须改成大写的,才能对外输出json格式的数据。正确写法如下:
type Student struct {
Id int
Name string
Score int
}
func main() {
s := Student{1, "小明", 99}
jsonS, _ := json.Marshal(s)
fmt.Println(string(jsonS))
}
问题:
func main() {
data := []int{1, 2, 3}
for _, value := range data {
value += 1
}
fmt.Println(data)
}
解决:
如上所示,我们本身是想对data里面的元素做加1操作的,但发现没有成功。那是因为,我们循环所引用的变量是临时变量,去修改的时候并不会改变数组中的原有结构。正确的做法应该是根据切片的索引去修改,其实就类似于php的foreach,改变数组中的值,也是需要根据索引去改的。如下所示:
func main() {
data := []int{1, 2, 3}
for key := range data {
data[key] += 1
}
fmt.Println(data)
}
问题:
func change(data [2]int) {
data[0] = 4
}
func main() {
data := [2]int{1, 2}
change(data)
fmt.Println(data)
}
解决:
如上所示,运行的结果是[1 2] ,而不是[4 2] 。原因是main方法中声明的data是数组,而go语言中的参数传递是值传递,所以不会改变原有的数组值。如果需要实现上述效果,可以改用切片,因为切片本身不会存储数据,他的底层数据会指向一个底层数组,因此在修改切片的元素时,会修改底层数组的相应元素,同时共享同一个底层数组的切片也会相应修改。正确做法如下所示:
func change(data []int) {
data[0] = 4
}
func main() {
data := []int{1, 2}
change(data)
fmt.Println(data)
}
问题:
func main() {
flag := 1
if true {
flag := 2
flag++
}
fmt.Println(flag)
}
解决:
如上所示,运行结果仍然是1,而不是2或者3。上述代码中,flag := 2,又重新声明了一个变量flag,但它作用的仅仅是if 判断逻辑里面的,并没有作用到整个main函数全局中。如果要正确影响,应将 := 改为 =,如下所示,结果则为3:
func main() {
flag := 1
if true {
flag = 2
flag++
}
fmt.Println(flag)
}
总结:以上,就是本人在实际开发中,结合自己所学,遇到的一些比较常见的坑点了。当然,也是比较基础的一些点。后面,我也会继续深入学习go,总结更多的经验!