开启生长之旅!这是我参与「日新计划 12 月更文应战」的第10天,点击查看活动概况

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

(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…