当前位置: 首页 > >

golang错题集

本文即Go语言的那些坑三。


不要对Go并发函数的执行时机做任何假设


请看下列的列子:


1import (
2 "fmt"
3 "runtime"
4 "time"
5)
6func main(){
7 names := []string{"lily", "yoyo", "cersei", "rose", "annei"}
8 for _, name := range names{
9 go func(){
10 fmt.Println(name)
11 }()
12 }
13 runtime.GOMAXPROCS(1)
14 runtime.Gosched()
15}

请问输出什么?

1annei
2annei
3annei
4annei
5annei

为什么呢?是不是有点诧异?

1import (
2 "fmt"
3 "runtime"
4 "time"
5)
6func main(){
7 names := []string{"lily", "yoyo", "cersei", "rose", "annei"}
8 for _, name := range names{
9 go func(){
10 fmt.Println(name)
11 }()
12 time.Sleep(time.Second)
13 }
14 runtime.GOMAXPROCS(1)
15 runtime.Gosched()
16}

打印结果:


1lily
2yoyo
3cersei
4rose
5annei

以上我们得出一个结论,不要对“go函数”的执行时机做任何的假设,除非你确实能做出让这种假设成为绝对事实的保证。

请看代码,试问能正常编译通过吗?


1import (
2 "fmt"
3)
4type Lili struct{
5 Name string
6}
7func (Lili *Lili) fmtPointer(){
8 fmt.Println("poniter")
9}
10func (Lili Lili) fmtReference(){
11 fmt.Println("reference")
12}
13func main(){
14 li := Lili{}
15 li.fmtPointer()
16}

答案:


1能正常编译通过,并输出"poniter"

感觉有点诧异,请接着看以下的代码,试问能编译通过?


1import (
2 "fmt"
3)
4type Lili struct{
5 Name string
6}
7func (Lili *Lili) fmtPointer(){
8 fmt.Println("poniter")
9}
10func (Lili Lili) fmtReference(){
11 fmt.Println("reference")
12}
13func main(){
14 Lili{}.fmtPointer()
15}

答案:


1不能编译通过。
2“cannot call pointer method on Lili literal”
3“cannot take the address of Lili literal”

是不是有点奇怪?这是为什么呢?其实在第一个代码示例中,main主函数中的“li”是一个变量,li的虽然是类型Lili,但是li是可以寻址的,&li的类型是Lili,因此可以调用Lili的方法。

请看下列代码,试问返回什么


1import (
2 "bytes"
3 "fmt"
4 "io"
5)
6const debug = true
7func main(){
8 var buf *bytes.Buffer
9 if debug{
10 buf = new(bytes.Buffer)
11 }
12 f(buf)
13}
14func f(out io.Writer){
15 if out != nil{
16 fmt.Println("surprise!")
17 }
18}

答案是输出:surprise。

1import (
2 "bytes"
3 "fmt"
4 "io"
5)
6const debug = false
7func main(){
8 var buf *bytes.Buffer
9 if debug{
10 buf = new(bytes.Buffer)
11 }
12 f(buf)
13}
14func f(out io.Writer){
15 if out != nil{
16 fmt.Println("surprise!")
17 }
18}

答案是:依然输出surprise。

1import (
2 "bytes"
3 "fmt"
4)
5func main(){
6 var buf *bytes.Buffer
7 if buf == nil{
8 fmt.Println("right")
9 }
10}

还是输出: right

1import (
2 "bytes"
3 "fmt"
4 "io"
5)
6const debug = false
7func main(){
8 var buf io.Writer //原来是var buf *bytes.Buffer
9 if debug{
10 buf = new(bytes.Buffer)
11 }
12 f(buf)
13}
14func f(out io.Writer){
15 if out != nil{
16 fmt.Println("surprise!")
17 }
18}

将map转化为json字符串的时候,json字符串中的顺序和map赋值顺序无关


请看下列代码,请问输出什么?若为json字符串,则json字符串中key的顺序是什么?


1func main() {
2 params := make(map[string]string)
3 params["id"] = "1"
4 params["id1"] = "3"
5 params["controller"] = "sections"
6 data, _ := json.Marshal(params)
7 fmt.Println(string(data))
8}

答案:输出{"controller":"sections","id":"1","id1":"3"}

请看以下程序,程序想要输出json数据中整型id加上3的值,请问程序会报错吗?


1func main(){
2 jsonStr := `{"id":1058,"name":"RyuGou"}`
3 var jsonData map[string]interface{}
4 json.Unmarshal([]byte(jsonStr), &jsonData)
5 sum := jsonData["id"].(int) + 3
6 fmt.Println(sum)
7}

答案是会报错,输出结果为:



panic: interface conversion: interface {} is float64, not int

1使用 Golang 解析 JSON 格式数据时,若以 interface{} 接收数据,则会按照下列规则进行解析:


bool, for JSON booleans
float64, for JSON numbers
string, for JSON strings
[]interface{}, for JSON arrays
map[string]interface{}, for JSON objects
nil for JSON null

1应该改为:

**即使在有多个变量、且有的变量存在有的变量不存在、且这些变量共同赋值的情况下,也不可以使用:=来给全局变量赋值**

:=往往是用来声明局部变量的,在多个变量赋值且有的值存在的情况下,:=也可以用来赋值使用,例如:

1msgStr := "hello wolrd"

但是,假如全局变量也使用类似的方式赋值,就会出现问题,请看下列代码,试问能编译通过吗?

1var varTest string
2func test(){
3 varTest, err := function()
4 fmt.Println(err.Error())
5}
6func function()(string, error){
7 return "hello world", errors.New("error")
8}
9func main(){


答案是:通不过。输出:

1varTest declared and not used


但是如果改成如下代码,就可以通过:

1var varTest string
2func test(){
3 err := errors.New("error")
4 varTest, err = function()
5 fmt.Println(err.Error())
6}
7func function()(string, error){
8 return "hello world", errors.New("error")
9}


输出:

1error



这是什么原因呢?
答案其实很简单,在test方法中,如果使用varTest, err := function()这种方式的话,相当于在函数中又定义了一个和全局变量varTest名字相同的局部变量,而这个局部变量又没有使用,所以会编译不通过。

原文发布时间为:2018-07-25
本文作者:Golang语言社区
本文来自云栖社区合作伙伴“[Golang语言社区](https://mp.weixin.qq.com/s/gjOTdEVyhHAiG4nK_ZrOVw)”,了解相关信息可以关注“Golang语言社区”。






相关资源:react-错题集WEBAPP



友情链接: year2525网 工作范文网 QS-ISP 138资料网 528200 工作范文网 baothai 表格模版