Loop: forn := 0; n < len(src); n += size { switch { case src[n] < sizeOne: if validateOnly { break } size = 1 update(src[n]) case src[n] < sizeTwo: ifn+1 >= len(src) { err = errShortInput break Loop } if validateOnly { break } size = 2 update(src[n] + src[n+1]<<shift) } }
Type switch
用于动态地发现接口变量类型,使用
类型断言
并在括号中传入
type
。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
var t interface{} t = functionOfSomeType() switch t := t.(type) { default: fmt.Printf("unexpected type %T\n", t) // %T prints whatever type t has casebool: fmt.Printf("boolean %t\n", t) // t has type bool caseint: fmt.Printf("integer %d\n", t) // t has type int case *bool: fmt.Printf("pointer to boolean %t\n", *t) // t has type *bool case *int: fmt.Printf("pointer to integer %d\n", *t) // t has type *int }
new和make
Go有两个基本分配操作,new和make,new为变量分配内存并置零(不同于其它语言的初始化)。
make则为slice , map和chan专用的,它不返回零值变量,而是初始化。
slice
slice
其实是对
array
进行了再包装(pointer, length, and capacity),它类似指针传递,但需要注意类似
append
这样的操作返回的是新的slice。
func init() { ifuser == ""{ log.Fatal("$USER not set") } ifhome == ""{ home = "/home/" + user } if gopath == ""{ gopath = home + "/go" } // gopath may be overridden by --gopath flag on command line. flag.StringVar(&gopath, "gopath", gopath, "override default GOPATH") }
方法:Pointers vs. Values
receiver
为值的方法可被值和指针调用,而指针
receiver
的方法只能被指针调用。
for range中的变量
for i:=range varaible
中,变量
i
会在每一轮循环中重复使用,如果直接在匿名函数中使用i,将易产生问题,这里有个种方式可行。一、使用带参数的匿名函数将i作为参数传递;二、在循环体开始处使用新变量保存i值,如
i:=i
,这是合法的。