:=
一定要給初值
b:=3
baz:= []int {3,4,5}
baz:= [3]int // error! 缺乏初值
- var 可以給初值也可以不給
var a = int(3) // 給初值
var b // 不給初值
println("b initial val=", b) //會有預設初值 0
b = 3 // 事後 assign
a := 3 // error! :=是宣告, 已經宣告過了, 不可以重複宣告
var az []int=[]int {3,4,5} //給初值
var bz []int //沒給初值
bz = []int{5, 6, 7, 9, 3} // 事後給
bz = []int{3, 7, 9, 11, 5} // 可以重複給, 原本內容會被gc?
- 在function 外只能用
var
package main
import "fmt"
type Vertex struct {
Lat, Long float64
}
var m map[string]Vertex
func main() {
m = make(map[string]Vertex)
m["Bell Labs"] = Vertex{
40.68433, -74.39967,
}
fmt.Println(m["Bell Labs"])
}
var ary [5]int
ary[1]=33 // ok
ary[6]=77 // error! out of range
ary=[5]int {7,8,9,10,11} // ok!
ary=[3]int {3,4,5} //error! 不同長度的array會被視為不同type, [3]int 不能直接assign給 [5]int
var ary1 []int
ary1=[]int {3,4,5} //ok
ary1=[]int {4,5,6,7} // ok
ary1=[2]int {1,2} // error! 會被視為不同type, [2]int 與 []int 不能直接assign,
ary1=[]int {1,2} // ok
- http://golang.org/doc/effective_go.html#arrays
- Arrays are values. Assigning one array to another copies all the elements.
- In particular, if you pass an array to a function, it will receive a copy of the array, not a pointer to it.
- The size of an array is part of its type. The types [10]int and [20]int are distinct. 長度不同type就不同
- 資料很大記得改用pointer to array or slice
func passptr(aryptr *[4]int) {
aryptr[1] = 999 // reference through pointer is the same way as accessing variable
}
func passslice(arysl []int) {
arysl[1] += 1 // reference through pointer is the same way as accessing variable
}
func array_pass() {
ary1 := [4]int{4, 5, 6, 7}
passptr(&ary1)
fmt.Println("ary1 becomes ", ary1)
passslice(ary1[:])
fmt.Println("ary1 becomes ", ary1)
}
- most array programming in Go is done with slices rather than simple arrays.
- _If the data exceeds the capacity, the slice is reallocated. _
func fixed_length_array_not_appendable() {
a := [2]string{"John", "Paul"}
fmt.Println("len(a)=", len(a), "cap(a)=", cap(a))
//a = append(a, "mary") // array size 固定, 不可以append
}
func append_to_slice_pointing_array() {
a := [2]string{"John", "Paul"}
asl := a[:]
fmt.Println("len(asl)=", len(asl), "cap(asl)=", cap(asl))
asl = append(asl, "mary") // trigger an reallocation
// slice 可以自由 append 萬一實際容量不夠, 它會自動realloc
fmt.Println("len(asl)=", len(asl), "cap(asl)=", cap(asl))
fmt.Println("asl=", asl)
}
- new 都是單一值
v1:= new(Vertex)
- make可以拿來生成slice or map
u:=make(map[string]int)
bazb:=make([]int,5)
- 都不能設初值
v1:= new(Vertex){3,4} //error
bazb:=make([]int,5){1,2,3,4,5} //error
- 下列四個是否一樣?
var ary1 [5]int
ary2:=[5]int{}
var ary3 = make([]int, 5)
ary4:=make([]int,5)
result
ary1 type=[5]int, len=5, content=[0 0 0 0 0]
ary2 type=[5]int, len=5, content=[0 0 0 0 0]
ary3 type=[]int, len=5, content=[0 0 0 0 0]
ary4 type=[]int, len=5, content=[0 0 0 0 0]
- make 與直接宣告的差異
var ary1 [5]int
fmt.Printf("ary1 type=%T, len=%d, content=%v\n", ary1, len(ary1), ary1)
var ary2 = make([]int, 5)
fmt.Printf("ary2 type=%T, len=%d, content=%v\n", ary2, len(ary2), ary2)
// output
//ary1 type=[5]int, len=5, content=[0 0 0 0 0]
//ary2 type=[]int, len=5, content=[0 0 0 0 0]
[]
其實叫做slice
, 彈性比fixed length array 高
var ary1 []int = []int{1, 2}
fmt.Printf("ary1 type=%T, len=%d, content=%v\n", ary1, len(ary1), ary1)
// result: ary1 type=[]int, len=2, content=[1 2]
ary1 = append(ary1, 44)
fmt.Printf("ary1 type=%T, len=%d, content=%v\n", ary1, len(ary1), ary1)
// result: ary1 type=[]int, len=3, content=[1 2 44]
var ary2 [2]int
fmt.Printf("ary2 type=%T, len=%d, content=%v\n", ary2, len(ary2), ary2)
// result: ary2 type=[2]int, len=2, content=[0 0]
ary2 = append(ary2, 44) // error! first argument to append must be slice; have [2]int
- 參考 http://blog.golang.org/slices
- 重點節錄 it is not a pointer to the first array element (as would be the case in C). This means that when you assign or pass around an array value you will make a copy of its contents. (To avoid the copy you could pass a pointer to the array, but then that's a pointer to an array, not an array.
- so
ary1 := [4]int{4, 5, 6, 7}
ary2 := ary1
ary1[2] = 999
fmt.Println("ary1=", ary1, "ary2=", ary2)
//result
ary1= [4 5 999 7] ary2= [4 5 6 7]
[...]
代表自動算count element , 跟[]
(slice) 意義不一樣
ary1 := [...]int{4, 5, 6, 7}
ary2 := ary1
ary1[2] = 999
fmt.Println("ary1=", ary1, "ary2=", ary2)
fmt.Printf("ary1's type = %T , ary2's type = %T\n", ary1, ary2)
//result:
//ary1= [4 5 999 7] ary2= [4 5 6 7]
//ary1's type = [4]int , ary2's type = [4]int
- pointer to array 長這樣
ary1 := [4]int{4, 5, 6, 7}
aryptr1 := new([4]int)
aryptr1 = &ary1
fmt.Printf("aryptr1's type = %T\n", aryptr1)
aryptr1[1] = 999 // reference through pointer is the same way as accessing variable
fmt.Println("ary1 becomes ", ary1)
aryptr1[5] = 99 // error! Unlike C, in Go pointers have range protection
- interface 當func parameter 的type, caller可以傳pointer 或var本身, it dependents the variable's type implementation
type Person interface {
getage() int
}
type Farmer struct {
age int
}
func (f *Farmer) getage() int {
return f.age
}
func showage(p Person) {
println("the age is ", p.getage())
}
type Carpenter struct {
age int
}
func (cp Carpenter) getage() int {
return cp.age
}
func main() {
f := Farmer{age: 10}
showage(&f)
//showage(f) // error Farmer doesn't implement Person
cp := Carpenter{age: 12}
showage(cp)
//showage(&cp) // error! *Carpenter doesn't implement Person
}
- 這個例子中我們可以說
*Farmer
implement了Person
interface, 但Farmer
並沒有Carpenter
implement了Person
interface, 但*Carpenter
並沒有
- 為你的type定義
String
function, 可以讓你的type用fmt.Println
印出來
type CBack struct {
id int
d string
}
func (cb CBack) String() string {
return fmt.Sprintf("id=%d, d=%s", cb.id, cb.d)
}
func main () {
cb := CBack{id: 3, d: "hello"}
fmt.Println("cb is ", cb)
}
- https://groups.google.com/forum/#!topic/golang-nuts/84GCvDBhpbg To convert variable v to type T, you would do: T(v)
map 一定要用make 才會指到實際map變數, 不然只是一個空的 nil map ( 意思是沒有指到任何空間的 reference map)
Map types are reference types, like pointers or slices, and so the value of m above is nil; it doesn't point to an initialized map. A nil map behaves like an empty map when reading, but attempts to write to a nil map will cause a runtime panic; don't do that. To initialize a map, use the built in make function: