Go语言条件块外变量异常:conn赋值后仍为空的问题排查
问题分析与解决
你的问题出在Go语言的短变量声明(:=)作用域上:
函数顶部声明的var conn *kafka.Conn是函数级别的变量,但在if/else分支里,你用了conn, err := ...这种写法——:=会在当前分支的局部作用域内创建一个新的conn变量,这个局部变量会遮蔽外层的函数级conn。当分支执行完毕,局部conn被销毁,外层的conn始终是初始的nil,所以分支外调用conn.ReadPartitions()时会发现它为空。
修复方案
核心是避免在分支里重新声明conn,改用赋值语句给外层变量赋值:
- 提前在函数顶部声明
err变量,避免用:=触发新变量声明 - 分支内使用普通赋值运算符
=给外层的conn赋值 - 把
defer conn.Close()移到分支外,确保只执行一次(且只有连接成功时才会执行到这里)
修改后的代码:
func CheckKafkaReadPartitions(kafkabroker string, topic string, conf config.Config) bool { var conn *kafka.Conn var err error // 提前声明err,避免分支内用:=创建新变量 if conf.TlsEnabled { d := &kafka.Dialer{ TLS: &tls.Config{}, } // 用=赋值,直接修改外层的conn变量 conn, err = d.Dial("tcp", kafkabroker) log.Info("conn is: ", conn) log.Info("Using TLS connection") if err != nil { log.WithError(err).Warn("Kafka broker connection error") return false } } else { // 同样用=赋值给外层conn conn, err = kafka.Dial("tcp", kafkabroker) log.Info("conn is: ", conn) log.Info("Using Plaintext connection") if err != nil { log.WithError(err).Warn("Kafka broker connection error") return false } } // 连接成功后统一延迟关闭,避免每个分支重复写defer defer conn.Close() log.Info("conn is: ", conn) log.Info("Reading Partitions") partitions, err := conn.ReadPartitions() // SOME OTHER WORK }
内容的提问来源于stack exchange,提问作者MBA
相关产品推荐
相关产品推荐

