运算符
算数运算符
-
go里面没有三目运算符
-
自增自减只有后置,没有前置。且只能独立使用(单独一行),不能形如
b := a++
-
取模运算可以等价为 a%b=a-a/b*b
关系运算符/逻辑运算符/赋值运算符
没什么特殊,赋值运算符也有+= -=
等复合赋值
赋值运算符运算顺序从右往左,左边只能是变量,右边可以是变量、表达式、常量值
运算符优先级
没什么特殊,只有单目和赋值从右往左运算
-
括号
-
++,--,. ,->`
-
单目运算符,
!,&,*
等 -
算术运算符
-
移位运算符
-
关系运算符
-
位运算符
-
逻辑运算符
-
赋值运算符
-
逗号
输入语句
fmt.Scanln
。在换行时停止
var name string
var age byte
var sal float32
var isPass bool
fmt.Println("请输入姓名 ")
fmt.Scanln(&name)//注意取地址符号
fmt.Println("请输入年龄 ")
fmt.Scanln(&age)
fmt.Println("请输入薪水 ")
fmt.Scanln(&sal)
fmt.Println("请输入是否通过考试 ")
fmt.Scanln(&isPass)
fmt.Println(name , age, sal, isPass)
fmt.Scanf
。在空格停止
fmt.Println("请输入姓名 年龄 薪水 是否通过考试,用空格隔开 ")
fmt.Scanf("%s %d %f %t",&name , &age, &sal, &isPass)
fmt.Printf(" 名字是%v \n 年龄是%v \n 薪水是%v \n 是否通过考试%v \n",name,age,sal,isPass)
注意:变量前需要取地址符号
流程控制
顺序控制
程序从上到下逐行地执行,中间没有任何判断和跳转
注意事项
Golang中定义变量时采用合法地前向引用:先声明再用
分支控制
单分支
if 条件表达式{//条件表达式也可以加()但不推荐
执行代码块
}
注意:{}
必须有,即使代码只有一行。与c++不同
var age int
fmt.Scanln(&age)
if age>=18{
fmt.Println("成年了")
}else {
fmt.Println("没成年")
}
特殊写法
golang支持在if中,直接定义一个变量(只能一个变量),如下
if age :=20; age>=18{
fmt.Println("成年了")
}
双分支
if 条件表达式{
执行代码块
} else { //这个else不能写在下一行
执行代码块2
}
注意:else不能换行
多分支
if 条件表达式{
执行代码块
} else if 条件表达式2{
执行代码块2
}
...
else { //这个else不能写在下一行
执行代码块3
}
至多执行一个分支
注意事项总结
-
条件表达式也可以加()但不推荐
-
{}
必须有,即使代码只有一行。与c++不同 -
else不能换行
-
条件表达式不能是别的表达式(如赋值表达式),否则编译不通过,与c++不同
var b bool =true if b=false{ //b 执行代码块 }
嵌套分支
建议最多三层
switch
匹配项后面不需要加break,默认会有
case可以有多个表达式,用,
隔开
switch 表达式 {
case 表达式1,表达式2,...:
语句块
case 表达式3,表达式4,...:
语句块
default:
语句块
}
示例
var key byte
fmt.Scanf("%c",&key)
switch key {
case 'a':
fmt.Println("day1")
case 'b':
fmt.Println("day2")
case 'c':
fmt.Println("day3")
default:
fmt.Println("input error")
}
使用细节
-
case/switch后是一个表达式(即:常量值、变量、一个有返回值的函数等都可以)
-
case表达式的数据类型要和switch保持一致,否则编译出错
报错信息:var key byte fmt.Scanf("%c",&key) switch float32(key) { case float64('a'): fmt.Println("day1") default: fmt.Println("input error") }
invalid case float64('a') in switch on float32(key) (mismatched types float64 and float32)
- case后面可以带多个表达式,使用逗号间隔:
case 'a','d':
-
case后表达式如果是个常量(字面量),则要求不能重复,如果是变量,则编译能通过
-
case后面不需要带break,带了编译也能过
-
default语句不是必须
- switch后也可以不带表达式,类似if-else来使用。其实就是默认switch后是true,case后需要跟条件判断
var key int fmt.Scanf("%d",&key) switch { case key==10: fmt.Println("day1") break case key>10: fmt.Println("day2") case key<10: fmt.Println("day3") }
- switch后也可以直接声明/定义一个变量,分号结束,不推荐。
switch key:=10; { case key>10: fmt.Println("day1") case key<10: fmt.Println("day2") case key==10: fmt.Println("day3") default: fmt.Println("day99") }
- switch穿透:
fallthrough
,如果在case语句块后增加fallthrough
,则会继续执行下一个case,也叫switch穿透。只能穿透一层key:=90; switch key { case 90: fmt.Println("day1") key++ fallthrough case 91: fmt.Println(key) case 92: fmt.Println("day3") fallthrough default: fmt.Println(key) }
day1 91
- Type Switch:switch语句还可以被用于type-switch来判断某个interface变量中实际指向的变量类型
func test(int ) float32{ return 1.0 } func main(){ var x interface{} x = test switch i := x.(type){ case nil: fmt.Printf("x的类型:%T",i) case int: fmt.Printf("x是int型") case float64: fmt.Printf("x是float64") case func(int) float64: fmt.Printf("x是func(int)") case bool,string: fmt.Printf("x是bool或者string") default: fmt.Printf("未知") } }
循环控制
for
for i:=1;i<=10;i++{
fmt.Println(i)
}
注意事项
-
循环条件是返回bool的表达式
-
第二种表达方式:初始化和迭加写在别处,而不用加
;
。但是如果写了三者中的两个,则必须补满;
i:=1 for i<=10{ fmt.Println(i) i++ }
-
啥都不加相当于
for(;;)
死循环for {//也可以for ;; fmt.Println(i) break }
-
for-range方式,方便字符串和数组的遍历
var str string = "hello, world!" //index也可以置空 _ ,应该是表示不在乎,但必须要有个这个位置 for index, val:=range str{ fmt.Printf("index=%d, val=%c\n",index,val) }
这种方式即使字符串里存有中文字(不同编码方式),也可以正常输出(但是index会按照字符大小进行增加,汉字3字节),普通方式不行。
index=0, val=h index=1, val=e index=2, val=l index=3, val=l index=4, val=o index=5, val=! index=6, val=北 //注意顺序变了 index=9, val=京
普通方法需要用切片
[]rune
,如下var str string = "hello, world!北京" str2 := []rune(str) for i:=0;i<len(str2);i++{ fmt.Printf("%c \n",str2[i]) }
while和do...while
Go语言没有while和do...while!需要用for实现效果
break
count:=0
for{
//time.Now().Unix() 返回一个从1970:01:01到现在的秒数
rand.Seed(time.Now().Unix())//UnixNano()纳秒更随机
n:=rand.Intn(100)+1
count++
if(n==99){
break
}
}
fmt.Println(count)
注意事项
-
break语句出现在多层嵌套语句块中时,可以通过标签指明要终止到哪一层语句块
lable1: for i:=0;i<4;i++ { for j:=0;j<10;j++ { if j==2 { break lable1 } fmt.Println(j) } }
continue
goto
尽量避免使用goto
-
可以无条件转移到程序指定行
-
通常与条件语句配合
n:=30 fmt.Println("ok1") fmt.Println("ok2") if n>20{ goto lable1 } fmt.Println("ok3") fmt.Println("ok4") fmt.Println("ok5") lable1: fmt.Println("ok6") fmt.Println("ok7") fmt.Println("ok8")