【问题标题】:difference between declaring variables with var vs without var in go在 go 中使用 var 声明变量与不使用 var 之间的区别
【发布时间】:2013-05-31 15:12:30
【问题描述】:

我在step 35 in the tour of Go 练习中遇到了一些问题。

我的代码如下所示:

package main

import "code.google.com/p/go-tour/pic"

func Pic(dx, dy int) [][]uint8 {
    var pic = make([][]uint8, dy)
    for y := 0; y < dy; y++ {
        pic[y] = make([]uint8, dx)
        for x := 0; y < dx; x++ {
            pic[y][x] = uint8(x*y)
        } 
    }
    return pic
}

在寻找解决方案时,我发现 PeterSO's 代码完美运行

func main() {
    pic.Show(Pic)
}

func Pic(dx, dy int) [][]uint8 {
    pixels := make([][]uint8, dy)
    for y := 0; y < dy; y++ {
        pixels[y] = make([]uint8, dx)
        for x := 0; x < dx; x++ {
            pixels[y][x] = uint8(x * y)
        }
    }
    return pixels
}

我能看到的唯一区别是,我使用var 关键字定义pic 变量,而他的代码使用:= 赋值。现在,为什么我的代码不起作用?

【问题讨论】:

    标签: go indexoutofboundsexception


    【解决方案1】:

    你写的

    for x := 0; y < dx; x++ {
        pic[y][x] = uint8(x * y)
    }
    

    特别是:y &lt; dx,这会导致,

    panic: runtime error: index out of range
    

    我写的

        for x := 0; x < dx; x++ {
            pixels[y][x] = uint8(x * y)
        }
    

    特别是:x &lt; dx。因此,请将您的 y 更改为 x

    package main
    
    import "code.google.com/p/go-tour/pic"
    
    func Pic(dx, dy int) [][]uint8 {
        var pic = make([][]uint8, dy)
        for y :=0; y < dy; y++ {
            pic[y] = make([]uint8, dx)
            for x :=0; x<dx; x++ {
                pic[y][x] = uint8(x*y)
            } 
        }
        return pic
    }
    
    func main() {
        pic.Show(Pic)
    }
    

    http://play.golang.org/p/UvGgszFhl-

    Variable declarations

    变量声明创建一个变量,将一个标识符绑定到它 并给它一个类型和一个可选的初始值。

    VarDecl     = "var" ( VarSpec | "(" { VarSpec ";" } ")" ) .
    VarSpec     = IdentifierList ( Type [ "=" ExpressionList ] | "=" ExpressionList ) .
    

    Short variable declarations

    简短的变量声明使用以下语法:

    ShortVarDecl = IdentifierList ":=" ExpressionList.

    它是带有初始化器的常规变量声明的简写 表达式但没有类型:

    "var" IdentifierList = ExpressionList .
    

    与常规变量声明不同,短变量声明可以 重新声明变量,前提是它们最初是在 具有相同类型的相同块,并且至少有一个非空白 变量是新的。

    在您的代码var pic = make([][]uint8, dy) 和短格式pic := make([][]uint8, dy) 中都可以使用。

    【讨论】:

      【解决方案2】:

      如果您使用:=,则变量的类型隐含在符号右侧的表达式中。如果使用=,则不做任何假设,需要自己指定类型。

      在这种情况下,你应该这样写:

      var pic [][]uint8 = make([][]uint8, dy)
      

      但这确实更好,因为更短且更清晰:

      pic := make([][]uint8, dy)
      

      【讨论】:

      • var pic = make([][]uint8, dy) 有效,类型是推断出来的。不要写var pic [][]uint8 = make([][]uint8, dy),重复类型是多余的。
      • @Laurent:不正确,类型推断也适用于 =var v = expr
      • 另外,我认为你不能在函数定义之外使用:=,要使其成为全局,你必须在这种情况下使用var
      • 是的,这个答案根本不正确。我不会说:=“确实更好”。它不那么明显。我已经看到我的代码以及其他由于使用了:= 而导致隐藏变量的错误,这更难发现。
      猜你喜欢
      • 2012-11-28
      • 1970-01-01
      • 2011-12-12
      • 1970-01-01
      • 2014-03-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-21
      相关资源
      最近更新 更多