前言:
最近在学习golang,简单记录归纳了一些常用的语法,希望能够对小白选手有所帮助。
一、25个关键字
break | default | function | interface | select |
---|---|---|---|---|
case | defer | go | map | struct |
chan | else | goto | package | switch |
const | fallthrough | if | range | type |
continue | for | import | return | var |
二、变量
var vname type=value //标准定义
var vname1,vname2,vname3 type=v1,v2,v3
var vname1,vname2,vname3 =v1,v2,v3 //简化
vname1,vname2,vname3 :=v1,v2,v3 //再简化
三、常量
包括数值、布尔值、字符串等
const constantName = value
也可明确指定常量类型:
const pi float32=3.1415926
四、内置基础类型
布尔类型
var active bool //全局变量声明
active = true //赋值
valid :=false //简化声明
数值类型
- 整数类型:有符号int/无符号uint
- 浮点型:float
- 复数型:complex
var c complex64=5+5i
不同类型变量之间不可操作或赋值
字符串
字符串不可变化,若想改变可采用:
- 格式转换
s :="hello"
c :=[]byte(s) //转换为[]byte格式
c[0]='c'
s2 :=string(c) //再转换回string类型
fmt.Printf("%s",s2) //需要import “fmt”的packet
- slice切片
s :="hello"
s :="c"+s[1:]
fmt.Printf("%s",s)
用“+”连接各字符串
错误类型
error
五、iota枚举
const(
x=iota //x==0 初值为0,每调用一次+1
y=iota //x==1
z=iota //x==2
)
六、array数组
var arr [n]type //n长度,type元素类型
//eg.
var arr [4]int //定义
arr[0]=10 //赋值
arr :=[3]int{1,2,3}
arr :=[10]int{1,2,3} //其余元素默认为0
arr :=[...]int{1,2,3}//自动根据元素个数计算长度
//二维数组
arr2 :=[2][3]int{{1,2,3},{4,5,6}}
七、slice
不是真正意义的“动态数组”,而是引用类型。更推荐第一种定义方法,可避免在append元素前分配内存空间
var fslice []int //方法1:声明与array类似,只是不用定义长度
slice :=[]byte{'a','b','c'} //方法2:声明+初始化
从已存在的数组arr中再次声明一个slice a:
a=arr[2:4]
注意:a[i:j]开始位置是i,j为结束位置但不包含a[j]。arr[0:]等价于arr[0:n]。
slice包含:
- 指针,指向arr中slice的开始位置
- 长度,即slice的长度
- 最大长度,即slice开始位置到arr最后位置的长度
常用函数有:len、cap、append、copy,这里不再详细展开
八、map
类似于python中的dic字典 key-value
//声明方式1
var numbers map[string] int
//声明方式2
numbers :=make(map[string]int)
//赋值
numbers["one"]=1
numbers["two"]=2
//创建有初始元素的map
numbers :=map[string]int{"one":1, "two":2, "three":3}
//or
numbers :=map[string]int{
"one":1,
"two":2,
"three":3
}
若两个map同时指向一个底层,则一个改变,另一个也改变
九、make/new
- make用于内建类型(slice、map、channel),返回有初始值(非0)的T类型
- new用于各种类型的内存分配,返回指针*T
十、流程控制
if
if x :=computedvalue(); x>10{ //可在条件判断语句中声明变量,其作用域为该条件逻辑模块
//代码块
}else if{
//代码块
}else{
//代码块
}
goto
跳转到当前函数内定义的标签(标签名大小写敏感)
Here: //以:结尾代表标签
goto Here
for
for expression1; expression2; expression3{ //循环开始前调用;条件判断;每轮循环结束调用
//代码块
}
for ;sum<1000; {
}
//简化后:
for sum<1000{ //等价于while
}
for与range结合,可读取slice和map的数据
for k,v :=range map{ //k代表map的key,v代表map的value
}
for index,s :=range slice{ //index代表slice中元素的序号,s代表slice元素的值
}
for _,s :=range slice{} //"_"为占位符,丢弃不需要的返回值
switch
i :=10
switch i{
case 9: //默认每个case后有break
//代码块
case 10:
//代码块
fallthrough //强制执行后面的case代码
default:
//代码块
}
十一、函数
for funcName(input1 type1, input2 type2) (output1 type1, output2 type2){
//代码块
return value1,value2
}
for max(a, b int) int{ //省略第一个变量的类型,返回值也同理,省略返回值的命名
//代码块
return a
}
for mfun(a, b int) (int,int){
//代码块
return a*b, a+b //返回多个值
}
若函数是导出的(首字母大写),则最好命名返回值。
变参
for add1(a *int) int{
*a=*a+1 //修改了a的值,而不是copy
return *a //返回新值
}
函数作为值和类型
作用:可以把函数当作值来传递;便于扩展功能;便于自定义。
//定义
type typeName func(input1 inputType1, input2 inputType2)(result1 resultType1) //用type定义,拥有相同的参数和返回值
//示例
type testInt func(int) bool //定义一个函数类型,名为testInt,输入为int,输出为bool
func filter(slice []int, f testInt) []int{ //定义函数filter,输入为一个int型的slice和一个testInt型的函数f,输出为一个int型的slice
//代码块
}
十四、struct
type Person struct{ //名称person
name string //属性name/ age
age int
}
//声明方式1
var P Person //P为person类型的变量
P.name="sherley" //赋值
P.age=24
//声明方式2
P :=Person{"Tom",25} //按照顺序提供初始值
P :=Person{age:24, name:"Tom"}
struct的匿名字段:
type Student struct{
Person //默认Student包含了Person的所有字段
school string
}
mark :=Student{"mark",20,"BJTU"}
mark.Person.age=1 //Student可访问Person这个字段作为字段名
ps:若Person和Student中含有相同字段,则优先访问最外层的字段。
十五、method
func (r ReceiverType) funcName(parameters) (results) //r即接收对象,ReceiverType即接收对象的类型,funcName即method的名字
//eg.
func (r Rectangle) area() float64{
//代码块
}
即使method名字一样,若接收者不一样,则method不一样。
interface
interface是一组method的组合,用interface定义对象的一组行为。
Type Men interface{
SayHi() //前文定义好的方法
Sing()
}
一个函数把interface{}作为参数,则它可以接受任意类型的值作为参数;若一个函数返回interface{},就可以返回任意类型的值。<div>
interface变量存储的类型 求解方法:
- Comma-ok断言
value, ok=element.(type) //value为变量的值,ok为bool类型,type为断言的类型
- switch判断
有疑问加站长微信联系(非本文作者)