以下是 2019 年 6 月在 Twitter and Facebook 上发布的所有小测验及其解释。
测验 1
package mainimport ("fmt")func hello() []string {return nil}func main() {h := helloif h == nil {fmt.Println("nil")} else {fmt.Println("not nil")}}
选项
nilnot nilcompilation error
答案
not nil
我们将 function hello 赋给变量 h,第 12 行赋值的不是 hello() 的返回值。因此 h 不是 nil 值,程序将输出 not nil。
测验 2
package mainimport ("fmt""strconv")func main() {i := 2s := "1000"if len(s) > 1 {i, _ := strconv.Atoi(s)i = i + 5}fmt.Println(i)}
选项
21005compilation error
答案
2
这个问题比较棘手的部分是 12 行。i, _ := strconv.Atoi(s) 创建一个新变量 i,其作用域仅在 if 语句中。第 15 行打印的实际上是第 9 行定义的 i。而不是第 12 行定义的那个。因此,这个程序将打印 2。
测验 3
package mainimport ("fmt")func hello(num ...int) {num[0] = 18}func main() {i := []int{5, 6, 7}hello(i...)fmt.Println(i[0])}
选项
185Compilation error
答案
18
第 13 行切片 i 被传递给可变参数函数 hello() 函数。要知道为什么会发生这种情况,请阅读在 https://golangbot.com/variadic-functions/ 将一个切片传递给可变参数函数的部分。
如果你阅读了将切片传递给 https://golangbot.com/arrays-andslices/ 中的函数的部分,你可以理解对函数内部切片所做的更改对调用者是可见的。因此第 14 行将打印18。
测验 4
package mainimport ("fmt")func main() {a := [2]int{5, 6}b := [2]int{5, 6}if a == b {fmt.Println("equal")} else {fmt.Println("not equal")}}
选项
compilation errorequalnot equal
答案
equal
数组是 Go 中的值类型,可以进行比较。如果对应的元素相等,则两个数组值相等。在我们的例子中,a 和 b 是相等的,因此这个程序输出为 equal 。
测验 5
package mainimport "fmt"type rect struct {len, wid int}func (r rect) area() {fmt.Println(r.len * r.wid)}func main() {r := &rect{len: 5, wid: 6}r.area()}
选项
compilation error30
答案
30
这个程序将成功编译并输出 30。
在上面程序中的第 14 行,我们把 rect 的地址分配给了 r。你可能想知道,当我们在第15 行没有使用 (r).area() 时,为什么这个程序还能正常工作。 由于 area() 有一个值接收器,所以 Go 编译器足够智能,可以将 r.area() 解释为 (r).area() ,因此这个程序可以工作:)。
测验 6
package mainimport ("fmt")func main() {a := [5]int{1, 2, 3, 4, 5}t := a[3:4:4]fmt.Println(t[0])}
选项
34compilation error
答案
4
表达式
 
a[low : high : max]
构造与简单的切片表达式 a[low: high] 相同类型、相同长度和元素的切片。另外,它通过将结果的切片的容量设置为最大/低来控制它的容量。因此,第 9 行号中的切片 t 有一个元素 4,容量是 1。
测验 7
package mainimport ("fmt")type person struct {name string}func main() {var m map[person]intp := person{"mike"}fmt.Println(m[p])}
选项
compilation error01
答案
0
当我们尝试打印在字典中不存在的元素时,将打印该元素的零值。在我们的例子中,m 是 map[person]int 类型的字典。因为 p 在字典中不存在,int 类型的零值 0 就被打印出来。
测验 8
package mainimport ("fmt")func main() {i := 65fmt.Println(string(i))}
选项
A65compilation error
答案
A
A 的 unicode 码值是 65。因此,当 i 被类型转换为第 9 行中的字符串时。A 被打印出来。
测验 9
package mainimport ("fmt")func main() {a := 5b := 8.1fmt.Println(a + b)}
选项
13.113compilation error
答案
compilation error
a 的类型是 int, b 的类型是 float64。我们试图在第 10 行中相加 int 类型的值和 float64 类型的值。这是不允许的,因此程序将无法编译与错误。/prog。./prog.go:10:16: invalid operation: a + b (mismatched types int and float64)
测验 10
package mainimport ("fmt")func main() {var i interface{}if i == nil {fmt.Println("nil")return}fmt.Println("not nil")}
选项
nilnot nilcompilation error
答案
nil
空的 interface 的基础值和具体类型都为 nil。因此 i 为 nil。
测验 11
package mainimport ("fmt")func hello(i int) {fmt.Println(i)}func main() {i := 5defer hello(i)i = i + 10}
选项
515
答案
5
延迟函数的参数是在执行 defer 语句时求值,而不是在实际函数调用完成时求值。因此,当遇到第 15 行中的 defer 语句时,i 的值是 5。这个程序会输出 5。
测验 12
package mainimport ("fmt")func main() {fmt.Printf("%%")}
选项
0.0compilation error%
答案
%
格式说明符 %% 打印一个文字 % 符号。因此程序打印 %。
测验 13
package mainimport ("fmt")func main() {s := make(map[string]int)delete(s, "h")fmt.Println(s["h"])}
选项
runtime panic0compilation error
答案
0
第 9 中的 delete 函数不返回任何内容,如果指定的键不存在,则不执行任何操作。因为键 h 不存在,所以 delete 函数不会执行任何操作。第 10 行我们正在试着打印 s[“h”]。由于字典 s 没有关键字 h,它将返回默认的 int 值,因此输出 0。
测验 14
package mainimport ("fmt")func main() {i := -5j := +5fmt.Printf("%+d %+d", i, j)}
选项
-5 +5+5 +50 0
答案
-5 +5
格式说明符 %+d 中的 + 标志用于始终为数值打印符号。因此这个程序输出 -5 +5。
