本文已参与「新人创作礼」活动, 一起开启掘金创作之路。
-
常量声明
// iota 被调用就自增 // const() 中未指定则默认使用 同种规则 进行赋值 const ( b = "100" c // = "100" ) const ( i=1<<iota // 1<<0 = 1 j=3<<iota // 3<<1 = 6 k // 3<<2 = 12 l // 3<<3 = 24 ) -
编写时一行语句中末尾无需
;,若一行多句语句,则需用;断开 -
:=解构符号,只能用于函数体内 -
_空白符号 代表未使用的变量 -
v --equalsv -= 1,是语句有返回值,规减号只能在变量名后面! -
a.(type)仅能在switch中用,返回Type -
&取变量地址*取变量地址上的值 -
数组:
var array[3] int; array[0] = 1/array = [3]int{0, 1, 2} -
ptr := &array可拿到地址索引- c:
*(ptr+1) == array[1] - go:
ptr[1] == array[1](关于go操作数组地址的疑问可以看我提出的问题[点击跳转]
- c:
-
slice可变长数组(切片) <=> ArrayList:=将[]解构为index: value的键值对,默认返回value(map默认key:=将map[key]解构为value: contains
-
类型转换
type(value)类似py -
go关键字开启运行期携程 goroutine,同一个程序中所有的 goroutine 共享一个地址空间 -
chan- 不设缓冲区时,需同步接收,否则报错 fatal error: all goroutines are asleep - deadlock!
- 设置缓冲区时,类似IO流,(缓冲区满后)长时间阻塞仍报错 ↑
- close() 关闭通道
-
结构体的方法绑定
type Person struct { name string age int } // 方法声明结构体即可自动绑定 func (p Person) say() { println("Hello " + p.name) } -
接口
// 方法接口 type ToString interface { toString() string } // 接口方法需绑定结构体 // 实现方法即为实现接口 func (object Object) toString() string { return fmt.Sprintf("%s", &object) } -
异常
// 异常为定义在 builtin.go 中的 error 接口 // 实现 error 接口即为实现接口中定义的 Error() string 方法 func (object Object) Error() string { return fmt.Sprintf("Some errors occurred in %s and sub struct does not override this method!", object.toString()) } -
面向对象综合运用 - 仿 Object 类设计
package main import "fmt" // 方法接口 type ToString interface { toString() string } // 接口实现类 type Object struct { } // 实现方法即为实现接口 func (object Object) toString() string { return fmt.Sprintf("%s", &object) } // throws 方法 func (object Object) throws(msg string) (string, error) { return fmt.Sprintf("Error: %s", msg), object } // 实现error接口 func (object Object) Error() string { return fmt.Sprintf("Some errors occurred in %s and sub struct does not override this method!", object.toString()) } -
闭包 (闭包=函数+引用环境)
func main() { var txtSuffix = makeSuffix(".txt") var name = txtSuffix("file") fmt.Println(name) // file.txt } func makeSuffix(suffix string) func(name string) string { return func(name string) string { if !strings.HasSuffix(name, suffix) { return name + suffix } return name } } -
defer返回时压栈处理// 1 // Start // End // 阻塞... // (过了3s) // runtime: 1 // 3 // (过了3s) // runtime: 1 // 2 // (过了3s) // runtime: 1 // 1 func main() { fmt.Println(runtime.NumGoroutine()) fmt.Println("Start") defer runAndCheck(1) defer runAndCheck(2) defer runAndCheck(3) fmt.Println("End") } func runAndCheck(value int) { fmt.Printf("runtime: %d\n", runtime.NumGoroutine()) time.Sleep(time.Second * 3) fmt.Println(value) }从以上示例可以看出
defer关键字修饰的同一作用域内函数在同一个goroutine内栈式执行 (先入后出)defer修饰的函数在其父函数作用的 goroutine 内执行
-
init()执行包级别的初始化,先于mian(),自动被调用 -
WaitGroup同步等待机制,相当于Java中的CountDownLatchfunc main() { for i := 0; i < 10; i ++ { go show(i) waitGroup.Add(1) // 计数器 ++ } waitGroup.Wait() // 阻塞等待 fmt.Println("End") } func show(i int) { fmt.Println(i) defer waitGroup.Done() // 计数器 -- } -
查询接口
func main() { one := Type1{} two := Type2{} // 解构,查询接口并转换 cast, ok := two.(Type1) if ok { fmt.Println(cast) } }