// var res int res , errOrNot := returnSomething ( ) fmt . Printf ( "res: %v errOrNot: %v\n" , res , errOrNot ) fmt . Printf ( "errOrNot: %v\n" , errOrNot )
res: 0 errOrNot: true
errOrNot: false

显然,if条件语句块中获得的新errOrNot值没有按照预期被带出来,这是因为条件语句块内部的这个errOrNot是一个覆盖了外围errOrNot的全新短变量。

如果这样写:

package main
import "fmt"
func returnSomething() (int, bool) {
	return 0, true
func main() {
	var errOrNot = false
	a := 1
	if a > 0 {
		var res int
		res, errOrNot = returnSomething()
		fmt.Printf("res: %v errOrNot: %v\n", res, errOrNot)
	fmt.Printf("errOrNot: %v\n", errOrNot)
res: 0 errOrNot: true
errOrNot: true

可见,整个代码中就只有一个errOrNot变量。

这种错误在函数返回一个具名变量时也容易出现,因为具名变量也相当于声明了一个变量,此时这种错误往往也伴生在if语句或者for语句的条件块中:

func shadow() (err error) {
	x, err := Check1()
	if err != nil {
		return                //能正常返回错误
	if y, err := Check2(); err != nil {
		return            //返回nil
	fmt.Printf("x:%v y:%v\n", x, y)
	reutrn

所以,if语句或者for语句中使用短变量声明时一定注意。

常见的情形就是:在if条件语句块或for循环语句块中,使用“:=”给一个与外部同名的变量赋值直接看个例子:package mainimport "fmt"func returnSomething() (int, bool) { return 0, true}func main() { var errOrNot = false a := 1 if a > 0 { // var res int res, errOrNot := returnSomething() f 1.switch/case 后是一个表达式(即:常量,变量,一个有返回的函数都可以); 2.case后的各个表达式的值的数据类型,必须和switch的表达式数据类型一致; 3.case后面可以带多个表达式,使用逗号间隔; 4.case后面的表达式如果是常量值,则要求不能重复; 5.case后面不需要带break,程序匹配到一个case后就会执行对应的代码块,然后退出switch,如果一个都匹配不到,则执行default; 6.default语句不是必须的; 7.switch 后也可以不 for { phone_conn, err := phones[device_name].get_conn() if (net.TCPConn{}) == phone_conn || err != nil { log.Print... // 生成随机的32字节密钥和12字节的随机nonce key := make([]byte, 32) if _, err := rand.Read(key); err != nil { panic(err) nonce := make([]byte, 12) if _, err := rand.Read(nonce); err != nil { panic(err) // 明文数据 plaintext := []byte("Hello, world!") // 创建AES-GCM加密器 block, err := aes.NewCipher(key) if err != nil { panic(err) aead, err := cipher.NewGCM(block) if err != nil { panic(err) // 加密数据 ciphertext := aead.Seal(nil, nonce, plaintext, nil) // 输出加密后的数据和密钥、nonce fmt.Printf("Ciphertext: %s\n", hex.EncodeToString(ciphertext)) fmt.Printf("Key: %s\n", hex.EncodeToString(key)) fmt.Printf("Nonce: %s\n", hex.EncodeToString(nonce)) // 创建AES-GCM解密器 block, err = aes.NewCipher(key) if err != nil { panic(err) aead, err = cipher.NewGCM(block) if err != nil { panic(err) // 解密数据 plaintext, err = aead.Open(nil, nonce, ciphertext, nil) if err != nil { panic(err) // 输出解密后的数据 fmt.Printf("Plaintext: %s\n", plaintext) 注意:在实际使用中,密钥和nonce应该是固定的,而不是每次都随机生成。此外,nonce必须是唯一的,否则会导致安全问题。