英文:
Why am I getting "declared but not used"?
问题
这是因为在循环中,你使用了 :=
运算符来声明并初始化 prev_z
变量,这会创建一个新的 prev_z
变量,而不是更新外部的 prev_z
变量。因此,循环条件中的 prev_z
变量实际上没有被使用,而是在每次循环迭代时重新声明并初始化。要解决这个问题,你可以将 :=
运算符改为 =
运算符,以便在循环中更新外部的 prev_z
变量。修改后的代码如下:
func Sqrt(x float64) float64 {
z := 1.0
var prev_z float64
for (z - prev_z) != 0 {
prev_z = z
z -= (z*z - x) / (2*z)
fmt.Println(z)
}
return z
}
这样修改后,你就不会再收到 "prev_z declared but not used" 的错误提示了。
英文:
I'm taking "a tour of Go" and for one of the exercises I've written this function:
func Sqrt(x float64) float64 {
z := 1.0
var prev_z float64
for (z - prev_z) != 0 {
prev_z := z
z -= (z*z - x) / (2*z)
fmt.Println(z)
}
return z
}
Why does this give me "prev_z declared but not used"?
答案1
得分: 4
因为你在for循环内部声明了一个类型为float64的变量(prev_z),然后你又使用:=短声明运算符(在第5行)初始化了一个同名同类型的新变量。
以下是正确的代码:
func Sqrt(x float64) float64 {
z := 1.0
var prev_z float64
for (z - prev_z) != 0 {
prev_z = z
z -= (z*z - x) / (2*z)
fmt.Println(z)
}
return z
}
英文:
Because you are declaring a variable (prev_z) of type float64 inside the for loop. and after that you are again initializing a new variable with the same name and type using the := short declaration operator(in line 5).
below is the correct code:
func Sqrt(x float64) float64 {
z := 1.0
var prev_z float64
for (z - prev_z) != 0 {
prev_z = z
z -= (z*z - x) / (2*z)
fmt.Println(z)
}
return z
}
答案2
得分: 3
你的代码问题在于你在for循环内部使用了:=运算符重新声明了prev_z变量。这实际上创建了一个新的prev_z变量,其作用范围更窄,遮蔽了在循环外部声明的原始prev_z变量。由于这个新变量从未被使用,所以你会得到"prev_z declared but not used"的错误。你应该在循环内部使用=运算符而不是:=来将新值赋给现有的prev_z。
下面是修正后的代码:
func Sqrt(x float64) float64 {
z := 1.0
var prev_z float64
for (z - prev_z) != 0 {
prev_z = z
z -= (z*z - x) / (2*z)
fmt.Println(z)
}
return z
}
英文:
The issue in your code is that you're using the := operator to re-declare prev_z inside the for loop. This actually creates a new prev_z variable with a narrower scope that shadows the original prev_z variable declared outside of the loop. Since this new variable is never used, you get the "prev_z declared but not used" error, you should use the = operator instead of := inside the loop to assign the new value to the existing prev_z
This should work below
func Sqrt(x float64) float64 {
z := 1.0
var prev_z float64
for (z - prev_z) != 0 {
prev_z = z
z -= (z*z - x) / (2*z)
fmt.Println(z)
}
return z
}
答案3
得分: 0
每当你使用 := 时,它会在运行时生成一个新的变量,并从该运算符右侧的值推断出该变量的数据类型。所以如果你写:
a:=1
那么你实际上创建了一个名为a的int类型变量。
在你的代码中,在for循环内部你写了:
prev_z := z
这导致创建了一个名为prev_z的新变量,它遮蔽了外部上下文中的prev_z,并且因此未被使用。
英文:
Whenever you use := , It generates new variable on fly and infer data type of that variable from the value that is present on Right hand side of this operator. So if you write:
a:=1
Then you're essentialy creating variable name a of type int.
In your code inside for loop you've written:
prev_z := z
Which leads to the creation of new variable with name prev_z which overshadows prev_z in outer context and hence it gets remained unused.
答案4
得分: 0
作为对其他评论者的补充,这种现象被称为变量遮蔽。在使用条件语句和返回错误作为第二个参数的函数时,无意中使用变量遮蔽是一个常见的错误,特别是在if/for
块内部。
这本书《100个Go错误及其避免方法》(值得一读)中的例子说明了一个变量遮蔽的情况,导致一个始终为nil
的变量:
var client *http.Client ❶
if tracing {
client, err := createClientWithTracing() ❷
if err != nil {
return err
}
log.Println(client)
} else {
client, err := createDefaultClient() ❸
if err != nil {
return err
}
log.Println(client)
}
// 使用client变量
在这个例子中,我们首先声明了一个client变量。然后,在两个内部块中使用了短变量声明运算符(:=)将函数调用的结果赋值给内部的client变量,而不是外部的变量。结果,外部的变量始终为nil。
注意,这段代码可以编译通过,因为内部的client变量在日志调用中被使用。如果没有使用,我们将会得到编译错误,比如"client declared and not used"。
在你的情况下,只有一个变量,所以你只需要不使用短变量声明运算符:=
重新赋值prev_z
。但是如果有两个或更多的变量,你可以在if/for
块内部使用临时变量,或者在块外声明这些变量。
英文:
Just as a complement to other commenters. The name of this phenomenon is variable shadowing. It's a common mistake to use it unintentionally, especially when you have conditionals and functions that return errors as second arguments inside if/for
blocks.
This example from the book 100 Go Mistakes and How to Avoid Them (worth reading, btw) illustrates a case of variable shadowing that results in an always nil
variable:
> var client *http.Client ❶
> if tracing {
> client, err := createClientWithTracing() ❷
> if err != nil {
> return err
> }
> log.Println(client)
> } else {
> client, err := createDefaultClient() ❸
> if err != nil {
> return err
> }
> log.Println(client)
> }
> // Use client
>
> In this example, we first declare a client variable. Then, we use the
> short variable declaration operator (:=) in both inner blocks to
> assign the result of the function call to the inner client
> variables—not the outer one. As a result, the outer variable is always
> nil.
>
> NOTE This code compiles because the inner client variables are used in
> the logging calls. If not, we would have compilation errors such as
> client declared and not used.
In your case it's just one variable, so you just don't reassign prev_z
with the short assignment operator :=
.
But in the case of two or more variables, you could use temporary variables inside the if/for
block or declare the variables outside of the block.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论