Go语言开发小技巧&易错点100例(一)

简介: Go语言开发小技巧&易错点100例(一)

先罗列一下吧(技巧类用【技】表示,易错点用【易】表示):

(1)main函数提前退出【易】

(2)包循环依赖【易】

(3)fallthrough关键字【技】

(4)简式变量声明(i:=1)仅能在函数内部使用【易】

(5)interface断言【易】

正文:

1 main函数提前退出【易】

你是否遇见过这种情况:

func main() {
   go func() {
      fmt.Println("Hello goruntine")
   }()
   fmt.Println("Hello main")
}
复制代码

运行结果:

第一次运行:
Hello main
第n次运行:
Hello main
Hello goruntine
第n+1次运行:
Hello goruntine
Hello main
复制代码

为什么会导致这样的结果呢?

答案就是多线程,并且他们的线程并不是互斥的。

解决方式:

不专业的方式

func main() {
   go func() {
      fmt.Println("Hello goruntine")
   }()
   fmt.Println("Hello main")
   time.Sleep(time.Second * 5)
}
复制代码

专业的方式

func main() {
   group := sync.WaitGroup{}
   group.Add(1)
   go func() {
      defer group.Done()
      fmt.Println("Hello goruntine")
   }()
   fmt.Println("Hello main")
   group.Wait()
}
复制代码

2 包循环依赖错误【易】

先说明下场景:

我们在dao层的文件中定义结构体和其相关的dao层方法,但是在调用方法时(如插入数据的方法)会使用utils包中的工具方法对参数进行检查,而utils中的工具方法需要引用dao层的结构体才能够检查,因此出现了dao依赖utils包,utils包依赖dao包的情况,就导致了循环依赖的异常。

dao包文件:

package dao
import (
   "fmt"
   "other/article/utils"
)
type User struct {
   Name string
}
func InsertUser() {
   utils.CheckUser()
   fmt.Println("InsertUser")
}
复制代码

utils包文件:

package utils
import (
   "fmt"
   "other/article/dao"
)
func CheckUser() {
   user := dao.User{Name: "zs"}
   fmt.Println("CheckUser", user)
}
复制代码

main文件:

package main
import (
  "other/article/dao"
)
func main() {
   dao.InsertUser()
}
复制代码

运行结果:

package command-line-arguments
  imports other/article/dao
  imports other/article/utils
  imports other/article/dao: import cycle not allowed
复制代码

解决方式:

将dao层的结构体移到一个新包中,并且dao和utils都引用这个新包。

这个错误也告诉我们一个道理,就是代码要注意划分层次,低内聚,才能更好的增加代码的可读性。

3 fallthrough关键字【技】

Go里面switch默认相当于每个case最后带有break,匹配成功后不会自动向下执行其他case,而是跳出整个switch, 但是可以使用fallthrough强制执行后面的case代码。

func main() {
   i := 10
   switch i {
   case 1:
      fmt.Println(1)
   case 5:
      fmt.Println(5)
      fallthrough
   case 10:
      fmt.Println(10)
      fallthrough
   case 20:
      fmt.Println(20)
   default:
      fmt.Println("default")
   }
}
复制代码

运行结果:

10
20
复制代码

4 简式变量声明仅能在函数内部使用【易】

什么是简式变量声明呢,我们知道Go声明变量有两种方式

// 第一种
var i int
i = 10
// 第二种 (简式变量声明)
i := 10 
复制代码

而第二种变量声明就不可以在方法外使用

5 interface断言【易】

func main() {
   var value interface{}
   value = "hello"
   str := value.(string)
   fmt.Println(str)
   value = 100
   i := value.(int32)
   fmt.Println(i)
}
复制代码

运行结果:

hello
panic: interface conversion: interface {} is int, not int32
......
复制代码

解决方式:

在断言之前先做一个类型判断

func main() {
   var value interface{}
   value = 100
   switch value.(type) {
   case int32:
      fmt.Println(value.(int32))
   case string:
      fmt.Println(value.(string))
   case int:
      fmt.Println(value.(int))
   }
}
复制代码

当然GitHub有更好的方式可以将interface类型转化成我们需要的类型,比如cast插件。

今天的分享就到这里咯~

参考:

chai2010.cn/advanced-go…

errorsingo.com/

www.kancloud.cn/gopher_go/g…

blog.csdn.net/Guzarish/ar…


相关文章
|
算法 Java Go
【GoGin】(1)上手Go Gin 基于Go语言开发的Web框架,本文介绍了各种路由的配置信息;包含各场景下请求参数的基本传入接收
gin 框架中采用的路优酷是基于httprouter做的是一个高性能的 HTTP 请求路由器,适用于 Go 语言。它的设计目标是提供高效的路由匹配和低内存占用,特别适合需要高性能和简单路由的应用场景。
848 4
|
数据采集 数据挖掘 测试技术
Go与Python爬虫实战对比:从开发效率到性能瓶颈的深度解析
本文对比了Python与Go在爬虫开发中的特点。Python凭借Scrapy等框架在开发效率和易用性上占优,适合快速开发与中小型项目;而Go凭借高并发和高性能优势,适用于大规模、长期运行的爬虫服务。文章通过代码示例和性能测试,分析了两者在并发能力、错误处理、部署维护等方面的差异,并探讨了未来融合发展的趋势。
1338 0
|
JavaScript 前端开发 Java
【GoWails】Go做桌面应用开发?本篇文章带你上手Wails框架!一步步带你玩明白前后端双端的数据绑定!
wails是一个可以让你使用Go和Web技术编写桌面应用的项目 可以将它看作Go的快并且轻量级的Electron替代品。可以使用Go的功能,并结合现代化UI完成桌面应用程序的开发
1906 5
|
存储 安全 Java
【Golang】(4)Go里面的指针如何?函数与方法怎么不一样?带你了解Go不同于其他高级语言的语法
结构体可以存储一组不同类型的数据,是一种符合类型。Go抛弃了类与继承,同时也抛弃了构造方法,刻意弱化了面向对象的功能,Go并非是一个传统OOP的语言,但是Go依旧有着OOP的影子,通过结构体和方法也可以模拟出一个类。
577 2
|
Cloud Native 安全 Java
Go:为云原生而生的高效语言
Go:为云原生而生的高效语言
860 1
|
Cloud Native Go API
Go:为云原生而生的高效语言
Go:为云原生而生的高效语言
740 0
|
Cloud Native Java Go
Go:为云原生而生的高效语言
Go:为云原生而生的高效语言
577 0
|
Cloud Native Java 中间件
Go:为云原生而生的高效语言
Go:为云原生而生的高效语言
608 0
|
Cloud Native Java Go
Go:为云原生而生的高效语言
Go:为云原生而生的高效语言
1759 0
|
编译器 Go
揭秘 Go 语言中空结构体的强大用法
Go 语言中的空结构体 `struct{}` 不包含任何字段,不占用内存空间。它在实际编程中有多种典型用法:1) 结合 map 实现集合(set)类型;2) 与 channel 搭配用于信号通知;3) 申请超大容量的 Slice 和 Array 以节省内存;4) 作为接口实现时明确表示不关注值。此外,需要注意的是,空结构体作为字段时可能会因内存对齐原因占用额外空间。建议将空结构体放在外层结构体的第一个字段以优化内存使用。

热门文章

最新文章