go语言常见坑

栏目: Go · 发布时间: 5年前

内容简介:学习go语言有段时间了,这门语言确实极具生产力,虽然都说简单,但是由于编程和常见的OO语言套路差别有点大,很多地方还是需要调整对已有语言的认识,这里记下遇到的一些坑,供有需要的朋友查阅。传统语言中对主入口的要求是main函数,如c++/java等,只需要保证这点即可,但是在如下,在一个main包定义如下函数

学习 go 语言有段时间了,这门语言确实极具生产力,虽然都说简单,但是由于编程和常见的OO语言套路差别有点大,很多地方还是需要调整对已有语言的认识,这里记下遇到的一些坑,供有需要的朋友查阅。

1.main包的唯一性

传统语言中对主入口的要求是main函数,如c++/java等,只需要保证这点即可,但是在 go中还需要保证main包的唯一性

如下,在一个main包定义如下函数

  1. package main

  2. import "fmt"

  3. func func1 () {

  4. fmt.Println( "test func1" )

  5. }

然后在另一个main包的main函数中如下调用

  1. package main

  2. import "fmt"

  3. func main () {

  4. //尝试1-尝试调用同目录下另一个main包中的函数

  5. //func1()

  6. }

报错如下:

common_point\test_main1.go:63:2: undefined: func1

可以看到,两个main包实际上是相互不可见的,对于自己来说都是唯一的。需要提下的是,实际项目中,可以 同一目录下包含多个main包,只要不相互调用 ,go build/run xxx指明对应main包文件编译运行即可,这样处理的目的在于使项目结构都清晰,同时兼容一个项目存在多个入口的情况。

2.如何跳出for select 循环

通常在for循环中,使用break可以跳出循环,但是注意在go语言中,for select配合时,break并不能跳出循环。

如下代码:

  1. func testSelectFor (chExit chan bool ) {

  2. for {

  3. select {

  4. case v, ok := <-chExit:

  5. if !ok {

  6. fmt.Println( "close channel 1" , v)

  7. break

  8. }

  9. fmt.Println( "ch1 val =" , v)

  10. }

  11. }

  12. fmt.Println( "exit testSelectFor" )

  13. }

如下调用:

  1. //尝试2 select for 跳出循环

  2. c := make ( chan bool )

  3. go testSelectFor(c)

  4. c <- true

  5. c <- false

  6. close (c)

  7. time.Sleep(time.Duration( 2 ) * time.Second)

运行结果如下,可以看到break无法跳出循环:

  1. ...

  2. close channel 1 false

  3. close channel 1 false

  4. close channel 1 false

  5. close channel 1 false

  6. ...

为了解决这个问题,需要设置标签, break 标签或goto 便签即可跳出循环 ,如下两种方法均可。

  1. func testSelectFor2 (chExit chan bool ) {

  2. EXIT:

  3. for {

  4. select {

  5. case v, ok := <-chExit:

  6. if !ok {

  7. fmt.Println( "close channel 2" , v)

  8. break EXIT //goto EXIT2

  9. }

  10. fmt.Println( "ch2 val =" , v)

  11. }

  12. }

  13. //EXIT2:

  14. fmt.Println( "exit testSelectFor2" )

  15. }

同样调用,输出结果如下:

  1. ch2 val = true

  2. ch2 val = false

  3. close channel 2 false

  4. exit testSelectFor2

3.如何在切片中查找

go中使用sort.searchXXX方法在 排序 好的切片中查找指定的方法,但是其返回结果很奇怪, 返回是对应的查找元素不存在时待插入的位置下标(元素插入在返回下标前) 。如下调用:

  1. //尝试3 search查找返回值

  2. s := [] string { "ab" , "ac" , "ac" , "bb" , "bb" , "ee" }

  3. fmt.Println( "s=" , s)

  4. fmt.Println(sort.SearchStrings(s, "aa" ))

  5. fmt.Println(sort.SearchStrings(s, "ac" ))

  6. fmt.Println(sort.SearchStrings(s, "ad" ))

  7. fmt.Println(sort.SearchStrings(s, "ff" ))

返回结果如下:

  1. s= [ab ac ac bb bb ee]

  2. 0

  3. 1

  4. 3

  5. 6

可以看到,单独根据返回值没法判断对应元素是否存在,封装如下函数:

  1. func IsExist (s [] string , t string ) ( int , bool ) {

  2. iIndex := sort.SearchStrings(s, t)

  3. bExist := iIndex!= len (s) && s[iIndex]==t

  4. return iIndex, bExist

  5. }


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Agile Web Development with Rails 4

Agile Web Development with Rails 4

Sam Ruby、Dave Thomas、David Heinemeier Hansson / Pragmatic Bookshelf / 2013-10-11 / USD 43.95

Ruby on Rails helps you produce high-quality, beautiful-looking web applications quickly. You concentrate on creating the application, and Rails takes care of the details. Tens of thousands of deve......一起来看看 《Agile Web Development with Rails 4》 这本书的介绍吧!

MD5 加密
MD5 加密

MD5 加密工具

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具