// iffuncmain(){
x :=100if x >0{println("x")}elseif x <0{println("-x")}else{println("0")}}//switchfuncmain(){
x :=100switch{case x >0:println("x")case x <0:println("-x")default:println("0")}}
#forfuncmain(){for i :=0; i<5; i++{println(i)}for i:=4;i>=0; i--{println(i)}}funcmain(){
x :=[]int{100,101,102}//for...range 除元素外,还可返回索引for k, v :=range x {println(x,":", v)}}
3 函数
package main
import("errors""fmt")//函数可以定义多个返回值,甚至对其命名funcdiv(a, b int)(int,error){if b ==0{return0, errors.New("division by zero")}return a/b,nil}funcmain(){
a, b :=10,2//定义多个变量
c, err :=div(a, b)//接收多返回值
fmt.Println(c, err)}
函数是第一类型,可以作为参数或返回值
functest(x int)func(){//返回函数类型returnfunc(){//匿名函数println(x)//闭包}}funcmain(){
x :=100
f :=test(x)f()}
用defer定义延迟调用,无论函数是否出错,它都确保结束前被调用
package main
functest(a, b int){deferprintln("dispose...")//常用来释放资源,解除锁定,或执行一些清理操作//可定义多个defer, 按FILO顺序执行println(a /b)}funcmain(){test(10,0)}
4. 数据
切片(slice)可实现类似动态数组的功能
package main
import"fmt"funcmain(){
x :=make([]int,0,5)//创建容量为5的切片for i:=0;i<8;i++{
x =append(x, i)//追加数据,当超出容量限制时,自动分配更大的存储空间}
fmt.Println(x)}//输出//[0 1 2 3 4 5 6 7]
将字典(map)类型内置,可直接从运行时层面获取性能优化.
package main
import"fmt"funcmain(){
m :=make(map[string]int)//创建字典类型对象
m["a"]=1//添加或设置
x, ok := m["b"]//使用ok-idiom获取值,可知道key/value是否存在
fmt.Println(x, ok)delete(m,"a")//删除}/**
所谓ok-idiom模式,是指在多返回值中用一个名为ok的布尔值来标示操作是否成功。因为很多操作默认返回零值,所以必须额外说明
**/
结构体(struct)可欺匿名嵌入其他类型
package main
import"fmt"type user struct{
name string
age byte}type manager struct{
user //匿名嵌入其他类型
title string}funcmain(){var m manager
m.name ="Tom"//直接访问匿名字段的成员
m.age =29
m.title ="CTO"
fmt.Println(m)}/**
输出:
{{Tom 29} CTO}
**/
5. 方法
可以为当前包内的任意类型定义方法
package main
type X intfunc(x *X)inc(){//名称前的参数称作receiver,作用类似python self*x++}funcmain(){var x X
x.inc()println(x)}
还可直接调用匿名字段的方法,这种方式可实现与继承类似的功能
package main
import"fmt"type user struct{
name string
age byte}func(u user)ToString()string{return fmt.Sprintf("%+v", u)}type manager struct{
user
title string}funcmain(){var m manager
m.name ="Tom"
m.age =29println(m.ToString())//调用user.ToString()}
6. 接口
接口采用了duck type方式,也就是说无须在实现类型上添加显式声明。
package main
import"fmt"type user struct{
name string
age byte}func(u user)Print(){
fmt.Printf("%+v", u)}type Printer interface{//接口类型Print()}funcmain(){var u user
u.name ="Tom"
u.age =29var p Printer = u //只要包含接口所需的全部方法,即表示实现了该接口
p.Print()}//另有空接口类型interface{}, 用途类似OOP里的system.Object, 可接收任意类型对象
package main
//消费者funcconsumer(data chanint, done chanbool){for x:=range data {//接收数据,直到通道被关闭println("recv:", x)}
done <-true//通知main,消费结束}//生产者funcproducer(data chanint){for i:=0;i<4;i++{
data <- i //发送数据}close(data)//生产结束,关闭通道}funcmain(){
done :=make(chanbool)//用于接收消费结束信号
data :=make(chanint)//数据管道goconsumer(data, done)//启动消费者goproducer(data)//启动生产者<-done //阻塞,直到消费者发回结束信号}