以下是 2019 年 6 月在 Twitter and Facebook 上发布的所有小测验及其解释。

测验 1

  1. package main
  2. import (
  3. "fmt"
  4. )
  5. func hello() []string {
  6. return nil
  7. }
  8. func main() {
  9. h := hello
  10. if h == nil {
  11. fmt.Println("nil")
  12. } else {
  13. fmt.Println("not nil")
  14. }
  15. }

Run in playground

选项

  1. nil
  2. not nil
  3. compilation error

答案

  1. not nil

我们将 function hello 赋给变量 h,第 12 行赋值的不是 hello() 的返回值。因此 h 不是 nil 值,程序将输出 not nil。

测验 2

  1. package main
  2. import (
  3. "fmt"
  4. "strconv"
  5. )
  6. func main() {
  7. i := 2
  8. s := "1000"
  9. if len(s) > 1 {
  10. i, _ := strconv.Atoi(s)
  11. i = i + 5
  12. }
  13. fmt.Println(i)
  14. }

Run in playground

选项

  1. 2
  2. 1005
  3. compilation error

答案

  1. 2

这个问题比较棘手的部分是 12 行。i, _ := strconv.Atoi(s) 创建一个新变量 i,其作用域仅在 if 语句中。第 15 行打印的实际上是第 9 行定义的 i。而不是第 12 行定义的那个。因此,这个程序将打印 2。

测验 3

  1. package main
  2. import (
  3. "fmt"
  4. )
  5. func hello(num ...int) {
  6. num[0] = 18
  7. }
  8. func main() {
  9. i := []int{5, 6, 7}
  10. hello(i...)
  11. fmt.Println(i[0])
  12. }

Run in playground

选项

  1. 18
  2. 5
  3. Compilation error

答案

  1. 18

第 13 行切片 i 被传递给可变参数函数 hello() 函数。要知道为什么会发生这种情况,请阅读在 https://golangbot.com/variadic-functions/ 将一个切片传递给可变参数函数的部分。

如果你阅读了将切片传递给 https://golangbot.com/arrays-andslices/ 中的函数的部分,你可以理解对函数内部切片所做的更改对调用者是可见的。因此第 14 行将打印18。

测验 4

  1. package main
  2. import (
  3. "fmt"
  4. )
  5. func main() {
  6. a := [2]int{5, 6}
  7. b := [2]int{5, 6}
  8. if a == b {
  9. fmt.Println("equal")
  10. } else {
  11. fmt.Println("not equal")
  12. }
  13. }

Run in playground

选项

  1. compilation error
  2. equal
  3. not equal

答案

  1. equal

数组是 Go 中的值类型,可以进行比较。如果对应的元素相等,则两个数组值相等。在我们的例子中,a 和 b 是相等的,因此这个程序输出为 equal 。

测验 5

  1. package main
  2. import "fmt"
  3. type rect struct {
  4. len, wid int
  5. }
  6. func (r rect) area() {
  7. fmt.Println(r.len * r.wid)
  8. }
  9. func main() {
  10. r := &rect{len: 5, wid: 6}
  11. r.area()
  12. }

Run in playground

选项

  1. compilation error
  2. 30

答案

  1. 30

这个程序将成功编译并输出 30。

在上面程序中的第 14 行,我们把 rect 的地址分配给了 r。你可能想知道,当我们在第15 行没有使用 (r).area() 时,为什么这个程序还能正常工作。 由于 area() 有一个值接收器,所以 Go 编译器足够智能,可以将 r.area() 解释为 (r).area() ,因此这个程序可以工作:)。

测验 6

  1. package main
  2. import (
  3. "fmt"
  4. )
  5. func main() {
  6. a := [5]int{1, 2, 3, 4, 5}
  7. t := a[3:4:4]
  8. fmt.Println(t[0])
  9. }

Run in playground

选项

  1. 3
  2. 4
  3. compilation error

答案

  1. 4

表达式

  1. a[low : high : max]

构造与简单的切片表达式 a[low: high] 相同类型、相同长度和元素的切片。另外,它通过将结果的切片的容量设置为最大/低来控制它的容量。因此,第 9 行号中的切片 t 有一个元素 4,容量是 1。

测验 7

  1. package main
  2. import (
  3. "fmt"
  4. )
  5. type person struct {
  6. name string
  7. }
  8. func main() {
  9. var m map[person]int
  10. p := person{"mike"}
  11. fmt.Println(m[p])
  12. }

Run in playground

选项

  1. compilation error
  2. 0
  3. 1

答案

  1. 0

当我们尝试打印在字典中不存在的元素时,将打印该元素的零值。在我们的例子中,m 是 map[person]int 类型的字典。因为 p 在字典中不存在,int 类型的零值 0 就被打印出来。

测验 8

  1. package main
  2. import (
  3. "fmt"
  4. )
  5. func main() {
  6. i := 65
  7. fmt.Println(string(i))
  8. }

Run in playground

选项

  1. A
  2. 65
  3. compilation error

答案

  1. A

A 的 unicode 码值是 65。因此,当 i 被类型转换为第 9 行中的字符串时。A 被打印出来。

测验 9

  1. package main
  2. import (
  3. "fmt"
  4. )
  5. func main() {
  6. a := 5
  7. b := 8.1
  8. fmt.Println(a + b)
  9. }

Run in playground

选项

  1. 13.1
  2. 13
  3. compilation error

答案

  1. compilation error

a 的类型是 int, b 的类型是 float64。我们试图在第 10 行中相加 int 类型的值和 float64 类型的值。这是不允许的,因此程序将无法编译与错误。/prog。./prog.go:10:16: invalid operation: a + b (mismatched types int and float64)

测验 10

  1. package main
  2. import (
  3. "fmt"
  4. )
  5. func main() {
  6. var i interface{}
  7. if i == nil {
  8. fmt.Println("nil")
  9. return
  10. }
  11. fmt.Println("not nil")
  12. }

Run in playground

选项

  1. nil
  2. not nil
  3. compilation error

答案

  1. nil

空的 interface 的基础值和具体类型都为 nil。因此 i 为 nil。

测验 11

  1. package main
  2. import (
  3. "fmt"
  4. )
  5. func hello(i int) {
  6. fmt.Println(i)
  7. }
  8. func main() {
  9. i := 5
  10. defer hello(i)
  11. i = i + 10
  12. }

Run in playground

选项

  1. 5
  2. 15

答案

  1. 5

延迟函数的参数是在执行 defer 语句时求值,而不是在实际函数调用完成时求值。因此,当遇到第 15 行中的 defer 语句时,i 的值是 5。这个程序会输出 5。

测验 12

  1. package main
  2. import (
  3. "fmt"
  4. )
  5. func main() {
  6. fmt.Printf("%%")
  7. }

Run in playground

选项

  1. 0.0
  2. compilation error
  3. %

答案

  1. %

格式说明符 %% 打印一个文字 % 符号。因此程序打印 %。

测验 13

  1. package main
  2. import (
  3. "fmt"
  4. )
  5. func main() {
  6. s := make(map[string]int)
  7. delete(s, "h")
  8. fmt.Println(s["h"])
  9. }

Run in playground

选项

  1. runtime panic
  2. 0
  3. compilation error

答案

  1. 0

第 9 中的 delete 函数不返回任何内容,如果指定的键不存在,则不执行任何操作。因为键 h 不存在,所以 delete 函数不会执行任何操作。第 10 行我们正在试着打印 s[“h”]。由于字典 s 没有关键字 h,它将返回默认的 int 值,因此输出 0。

测验 14

  1. package main
  2. import (
  3. "fmt"
  4. )
  5. func main() {
  6. i := -5
  7. j := +5
  8. fmt.Printf("%+d %+d", i, j)
  9. }

Run in playground

选项

  1. -5 +5
  2. +5 +5
  3. 0 0

答案

  1. -5 +5

格式说明符 %+d 中的 + 标志用于始终为数值打印符号。因此这个程序输出 -5 +5。

原文链接

https://golangbot.com/june-2019-quiz-results/