英文:
Use variable out of conditional block in golang
问题
func CheckKafkaReadPartitions(kafkabroker string, topic string, conf config.Config) bool {
var conn *kafka.Conn
if conf.TlsEnabled {
d := &kafka.Dialer{
TLS: &tls.Config{},
}
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
}
defer conn.Close()
} else {
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 conn.Close()
}
log.Info("conn is: ", conn)
log.Info("Reading Partitions")
partitions, err := conn.ReadPartitions()
// SOME OTHER WORK
}
我注意到在调用ReadPartitions()方法时,即使在conn, err := kafka.Dial("tcp", kafkabroker)
或conn, err := d.Dial("tcp", kafkabroker)
中为其赋值,conn仍然为空。
我错过了什么?有没有办法在if/else块之外使用conn变量而不清空其内容?
英文:
func CheckKafkaReadPartitions(kafkabroker string, topic string, conf config.Config) bool {
var conn *kafka.Conn
if conf.TlsEnabled {
d := &kafka.Dialer{
TLS: &tls.Config{},
}
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
}
defer conn.Close()
} else {
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 conn.Close()
}
log.Info("conn is: ", conn)
log.Info("Reading Partitions")
partitions, err := conn.ReadPartitions()
// SOME OTHER WORK
}
I noticed that when calling ReadPartitions() method, conn is empty even after affecting values to it either in conn, err := kafka.Dial("tcp", kafkabroker)
or conn, err := d.Dial("tcp", kafkabroker)
What am I missing? Is there any way I could take conn var out of that if/else block without emptying its content?
答案1
得分: 2
所以基本上在这里发生的是变量屏蔽
。
Go语言有变量作用域,你可以通过在函数外部定义变量来使其成为全局作用域。然后你就可以在同一个包中的任何地方使用这个变量(或者如果它在你的代码中被导出,也可以在其他地方使用)。
然后你有在代码块中定义的变量。类似于var conn *kafka.Conn
,你可以从定义它的块中的任何地方访问这个变量(以及所有的子块)。
将代码块视为由花括号{}
括起来的代码。
这意味着if/else
是func
块下的独立块。
现在你需要理解的是=
和:=
之间的区别。
=
用于给变量赋值,而:=
是一个简写,用于声明和赋值一个变量。
所以通过使用conn, err := d.Dial("tcp", kafkabroker)
代码,你实际上是在if
块中声明了新的变量,并将它们的值从d.Dial
函数调用的返回值中赋给它们。
有一些情况下你可能想要这样做。最常见的情况是当你有一个启动goroutine的for循环,它使用来自外部块的变量。
英文:
So basically what happens here is a variable shadowing
.
Go has variable scopes, you can have a variable in a global scope by defining it outside of a function. Then you'll be able to use this variable anywhere in the same package (or if it is exported anywhere in your code).
Then you have the variables that are defined in a block of code. Similar to var conn *kafka.Conn
you can access this variable from everywhere in the block it was defined (and all the sub-blocks).
Think the blocks as the code that is enclosed by the curly brackets {}
This means that the if/else
are separate blocks under the func
block.
Now what you need to understand is the difference between the =
and :=
=
is used to assign a value to a variable while :=
is a shorthand that is used to declare and assign a variable.
So by using conn, err := d.Dial("tcp", kafkabroker)
code what you essentially do is declare new variables in the if
block and assign the values to them from the returned values of the d.Dial
func cal.
There are some cases that you may want to do that. The most common case is when you have a for loop that launches goroutines that uses a variable from an outer block.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论