在var中使用var vs without var声明变量之间的差异

时间:2013-06-05 03:36:48

标签: go indexoutofboundsexception

我在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
}

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

2 个答案:

答案 0 :(得分:5)

你写了

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

特别是:y < dx,导致

panic: runtime error: index out of range

我写了

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

特别是:x < 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-

go tour slices

  

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)都可以使用。

答案 1 :(得分:2)

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

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

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

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

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