Go言語のパッケージ名と変数名の罠
Go言語で以下のようなコードを書いて一瞬ハマったのでメモ。
package main import ( "fmt" "container/list" ) func main() { list := list.New() list.PushBack(1) list.PushBack(2) list.PushBack(3) for elem := list.Front(); elem != nil; elem = elem.Next() { fmt.Println(elem.Value) } list2 := list.New() list2.PushBackList(list) for elem := list2.Front(); elem != nil; elem = elem.Next() { fmt.Println(elem.Value) } }
$ go run Main.go # command-line-arguments ./Main.go:17: list.New undefined (type *list.List has no field or method New) $
‥えっ?
17行目は以下の部分。
list2 := list.New()
実はこれ、9行目の
list := list.New()
でlist
という名前の変数を定義することによって、パッケージ名よりも変数名の方が優先されてしまうことが原因(多分)。
なので、以下のようにでも書いてやり、パッケージ名と変数名の衝突を避けてやらないといけない。
package main import ( "fmt" "container/list" ) func main() { aList := list.New() aList.PushBack(1) aList.PushBack(2) aList.PushBack(3) for elem := aList.Front(); elem != nil; elem = elem.Next() { fmt.Println(elem.Value) } aList2 := list.New() aList2.PushBackList(aList) for elem := aList2.Front(); elem != nil; elem = elem.Next() { fmt.Println(elem.Value) } }
Javaだったら、以下のようなコードが許されるんだがな(良い悪いは別として)。
import java.util.ArrayList; import java.util.List; public class Main { public static void main(String[] args) { List<Integer> List = new ArrayList<>(); List.add(1); List.add(2); List.add(3); for (Integer elem : List) { System.out.println(elem); } List<Integer> List2 = new ArrayList<>(); List2.addAll(List); for (Integer elem : List2) { System.out.println(elem); } } }