2013-06-05 255 views
3

我在練習step 35 in the tour of Go時遇到了一些麻煩。聲明變量與var與無var之間的區別

這裏是我的代碼如下所示:

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變量,而他的代碼使用:=分配。現在,爲什麼我的代碼不工作?

回答

2

如果使用:=,則該變量的類型隱含在符號右側的表達式中。如果您使用=,則不做任何假設,您需要自行指定類型。

在這種情況下,你應該把它寫這樣的:

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

,但是這確實是好,因爲更短的和明確的:

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

'var pic = make([] [] uint8,dy)'是有效的,並且類型被推斷。不要寫'var pic [] [] uint8 = make([] [] uint8,dy)',重複該類型是多餘的。 – peterSO

+4

@Laurent:不正確,類型推理也適用於'=':'var v = expr'。 – zzzz

+1

另外,我認爲你不能在函數定義之外使用':='來使它成爲全局的,你必須在這種情況下使用'var'。 – siritinga

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)都將工作。

相關問題