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
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必须是唯一的,否则会导致安全问题。