Cir*_*i94 1 variables types go
我正在尝试初始化ErrNegativeSqrt,它是一个自定义的float64类型,但是如果我这样做,var它将无法正常工作。
看一下func Sqrt(x float64) (float64, error):
package main
import (
"fmt"
)
type ErrNegativeSqrt float64
func (e *ErrNegativeSqrt) Error() string {
return fmt.Sprint("cannot Sqrt negative number: %f", float64(*e))
}
func Sqrt(x float64) (float64, error) {
if x < 0 {
var err ErrNegativeSqrt = x
// This works: err := ErrNegativeSqrt(x)
return x, &err
}
z := x / 2
i := 1
for prev_z := 0.0; z != prev_z && Abs(z-prev_z) > 0.000000000000001; i++ {
prev_z = z
z -= (z*z - x) / (2 * z)
}
return z, nil
}
func Abs(x float64) float64 {
if x < 0 {
x = -x
}
return x
}
func main() {
fmt.Println(Sqrt(2))
fmt.Println(Sqrt(-2))
}
Run Code Online (Sandbox Code Playgroud)
错误是: ./prog.go:15:7: cannot use x (type float64) as type ErrNegativeSqrt in assignment
为什么会发生?与分配作业不一样:=吗?
在此变量声明中:
var err ErrNegativeSqrt = x
Run Code Online (Sandbox Code Playgroud)
您显式地指定err的类型ErrNegativeSqrt,然后尝试分配x给它,但是该x类型的类型float64不能分配给type的值ErrNegativeSqrt。可分配性规则不适用,float64并且ErrNegativeSqrt是2种不同的不同类型(尽管后者具有前者作为其基础类型,所以它们可以相互转换)。
使用此简短变量声明时:
err := ErrNegativeSqrt(x)
Run Code Online (Sandbox Code Playgroud)
您显式转换 x为ErrNegativeSqrt,因此x类型将被推断为ErrNegativeSqrt。
使用var关键字时,您可以这样做:
var err ErrNegativeSqrt = ErrNegativeSqrt(x)
Run Code Online (Sandbox Code Playgroud)
或者简单地:
var err = ErrNegativeSqrt(x)
Run Code Online (Sandbox Code Playgroud)
这正是short变量声明的缩写形式。
如前所述,var err ErrNegativeSqrt = x无效是因为可分配性规则不适用:
如果满足以下条件之一,则可将值
x分配给类型的变量T(“x可分配给T”):
如您所见,第二条规则“几乎”涵盖了我们要在此处执行的操作:
x的类型,V并且T具有相同的基础类型,并且至少是一种V或T不是定义的类型
之所以只是“几乎”,是因为ErrNegativeSqrt和float64都被命名(定义)了。
当您这样做时:
var err ErrNegativeSqrt = 1.0
Run Code Online (Sandbox Code Playgroud)
之所以有效,是因为您在这里分配一个无类型的 常量 1.0,该常量可以在需要时采用所需的类型(如上述分配中所示)。由于您要分配给errtype ErrNegativeSqrt,因此无类型的常量1.0可以采用该类型ErrNegativeSqrt(因为ErrNegativeSqrt的基础类型为float64,并且1.0是无类型的浮点常量)。这种情况恰好是最后一个可分配性规则:
如果您愿意:
var err ErrNegativeSqrt = float64(1.0) // FAIL!!
Run Code Online (Sandbox Code Playgroud)
这将再次失败,就像您在问题中的示例一样,因为在这里我们使用的类型化常量不能任意更改类型,没有可分配性规则允许这样做。
阅读博客文章The Go Blog:Constants,了解更多详细信息。