文章目录
- 三、运算符
- (一)、算术运算符
- (二)、关系运算符
- (三)、逻辑运算符
- (四)、位运算符
- (五)、赋值运算符
- (六)、其他运算符
- (七)、运算符优先级
- 四、条件语句
- (一)、if语句
- (二)、if...else语句
- (三)、if嵌套语句
- (四)、switch语句
- (五)、select语句
- 五、循环语句
- (一)、for循环
- (二)、break语句
- (三)、continue语句
- (四)、goto语句
三、运算符
Go语言的语言运算符大多和C语言一样。
(一)、算术运算符
Go语言算术运算符由+(加)、-(减)、*(乘)、/(除,求商)、%(求余)、++(自增)、–(自减)组成。
import main
import "fmt"
func main(){
var a int = 5
var b int = 2
fmt.Println(a+b)//7
fmt.Println(a-b)//3
fmt.Println(a*b)//10
fmt.Println(a/b)//2
fmt.Println(a%b)//1
a++//自增一
fmt.Println(a)//6
a--//自减一
fmt.Println(a)//5
}
(二)、关系运算符
Go语言的关系运算符由==(等于?)、!=(不等于?)、>(大于?)、<(小于?)、>=(大于等于?)、<=(小于等于?)组成。
package main
import "fmt"
func main(){
var a int = 5
var b int = 2
fmt.Println(a==b)//false
fmt.Println(a!=b)//true
fmt.Println(a>b)//true
fmt.Println(a<b)//false
fmt.Println(a>=b)//true
fmt.Println(a<=b)//false
}
(三)、逻辑运算符
Go语言的逻辑运算符由&&(逻辑与)、||(逻辑或)、!(非)组成。
package main
import "fmt"
func main(){
var a bool = true
var b bool = false
fmt.Println(a&&b)//false
fmt.Println(a||b)//true
fmt.Println(!b)//true
}
(四)、位运算符
Go语言的位运算符由&(按位与)、|(按位或)、(按位异或)、<<(按位左移n位,乘以2的n次方,n为无符号整型)、>>(按位右移n位,除以2的n次方)、&(按位置零)组成。
package main
import "fmt"
func main(){
var a uint = 5//对应二进制为0101
var b uint = 2//对应二进制为0010
fmt.Println(a&b)//0000 即0
fmt.Println(a|b)//0111 即7
fmt.Println(a^b)//0111 即7
fmt.Println(a<<b)//5*2^2 即20
fmt.Println(a>>b)//5/2^2 即1
//下面详细将接&^符号
fmt.Println(0&^0)//0
fmt.Println(1&^0)//1
fmt.Println(0&^1)//0
fmt.Println(1&^1)//0
fmt.Println(a&^b)//5
/*可以看出规律吗?看不出也没关系,我跟你讲
x&^y 根据y将x按位清零
如果y对应的位为0,则x对应的位不变;y对应的位为1,则x对应的位清零。
0110&^0010 = 0100
*/
}
(五)、赋值运算符
Go语言的赋值运算符由=(将表达式赋予左值)、+=(相加后赋值)、-=(相减后赋值)、*=(相乘后赋值)、/=(相除后赋值)、%=(求余后赋值)、<<=(左移后赋值)、>>=(右移后赋值)、&=(按位与后赋值)、^=(an按位异或后赋值)、|=(按位或后赋值)组成。
package main
import "fmt"
func main(){
var a int = 5//对应二进制为0101
var b int = 2//对应二进制为0010
a+=b//a=7
a-=b//a=3
a*=b//a=10
a/=b//a=2
a%=b//a=1
a<<=b//a=20
a>>=b//a=1
a&=b//a=0
a^=b//a=7
a|=b//a=7
}
(六)、其他运算符
Go的其他运算符主要指指针操作*(引用)、&(取址)、<-(用于通道)。
package main
import "fmt"
func main(){
var a uint = 5//对应二进制为0101
var b *uint = &a
fmt.Println(a)//5
fmt.Printlb(&a)//存放变量a的地址
fmt.Println(b)//指针b指向变量的地址,输出值和上面一样
fmt.Println(*b)//引用指针b所指向的地址,取其值
}
下面是Go语言的通道用法,用的就是<-运算符,详见Go通道chan用法。
package main
import (
"fmt"
)
func main() {
// 构建一个通道
ch := make(chan int)//:=代表赋值操作的是 根据值自行判定变量类型
// 开启一个并发匿名函数
go func() {
fmt.Println("start goroutine")
// 通过通道通知main的goroutine
ch <- 0
fmt.Println("exit goroutine")
}()
fmt.Println("wait goroutine")
// 等待匿名goroutine
fmt.Println("all done")
}
/*输出
wait goroutine
start goroutine
exit goroutine
all done*/
还有另一段代码
package main
import (
"fmt"
"time"
)
func main() {
// 构建一个通道
ch := make(chan int)
// 开启一个并发匿名函数
go func() {
// 从3循环到0
for i := 3; i >= 0; i-- {
// 发送3到0之间的数值
ch <- i
// 每次发送完时等待
time.Sleep(time.Second)
}
}()
// 遍历接收通道数据
for data := range ch {
// 打印通道数据
fmt.Println(data)
// 当遇到数据0时, 退出接收循环。如果继续发送,由于接收 goroutine 已经退出,没有 goroutine 发送到通道,因此运行时将会触发宕机报错。
if data == 0 {
break
}
}
}
(七)、运算符优先级
优先级 | 运算符 |
7 | ^ ! |
6 | * / % << >> & &^ |
5 | + - |
4 | == != < <= >= > |
3 | <- |
2 | && |
1 |
当然也可以通过使用括号来临时提升某个表达式的整体运算优先级。
四、条件语句
注意:Go 没有三目运算符,所以不支持 ?: 形式的条件判断。
(一)、if语句
if语句的原型如下:
if 布尔表达式{
//当布尔表达式为真时执行
}
package main
func main() {
var arg1 int = 10
if arg1 != 0 {
//do something
}
}
(二)、if…else语句
if…else语句的原型如下:
if 布尔表达式 {
//当布尔表达式为真时执行
} else {//注意这里的else不要放到后面
//当布尔表达式为假时执行
}
package main
func main() {
var arg1 int = 10
var arg2 int = 30
if arg1 != arg2 {
//do something
} else {
//do something
}
}
(三)、if嵌套语句
if嵌套语句的原型如下:
if 布尔表达式 1 {
//当布尔表达式1为真时执行
if 布尔表达式 2 {
//在布尔表达式2为真时执行
}
}
package main
func main() {
var arg1 int = 10
var arg2 int = 30
if arg1 != arg2 {
//do something
if arg1 > 10{
//do something
}
}
}
(四)、switch语句
switch语句的原型如下:
switch variable1{ //当variable1符合下面某一个case时执行对应程序
case value1:
…
case value2:
…
default:
…}
package main
func main() {
var arg1 int = 10
var arg2 int = 30
var num int
switch num {
case arg1:
//do something
case arg2:
//do something
fallthrough//强行执行下面的case,不进行判断是否为真
case 20:
//do something
default:
//do something
}
}
(五)、select语句
select 是 Go 中的一个控制结构,类似于用于通信的 switch 语句。每个 case 必须是一个通信操作,要么是发送要么是接收。select 随机执行一个可运行的 case。如果没有 case 可运行,它将阻塞,直到有 case 可运行。一个默认的子句应该总是可运行的。
select语句的原型如下:
select {
case communication clause :
statement(s)
case communication clause :
statement(s)
//可定义任意数量的 case
default : //可选
statement(s)
}
- 每个 case 都必须是一个通信。
- 所有 channel 表达式都会被求值。
- 所有被发送的表达式都会被求值。
- 如果任意某个通信可以进行,它就执行,其他被忽略。
- 如果有多个 case 都可以运行,Select 会随机公平地选出一个执行。其他不会执行。
否则:
- 如果有 default 子句,则执行该语句。
- 如果没有 default 子句,select 将阻塞,直到某个通信可以运行;Go 不会重新对 channel 或值进行求值。
package main
import (
"fmt"
"time"
)
func Chann(ch chan int, stopCh chan int) {
var i int
i = 10
for j := 0; j < 10; j++ {
ch <- i
time.Sleep(time.Second)
}
stopCh <- 10
}
func main() {
var c2, c3 chan int
var c1 chan int
var i1, i2 int
go Chann(c1, c2)
select {
case i1 = <-c1:
fmt.Printf("received ", i1, " from c1\n")
break
case c2 <- i2:
fmt.Printf("sent ", i2, " to c2\n")
break
case i3, ok := <-c3: // same as: i3, ok := <-c3
if ok {
fmt.Printf("received ", i3, " from c3\n")
} else {
fmt.Printf("c3 is closed\n")
}
break
default:
fmt.Printf("no communication\n")
break
}
}
最后附一个帮助理解goroutine的例程。
package main
import (
"fmt"
"time"
)
func main() {
//make the request chan chan that both go-routines will be given
requestChan := make(chan chan string)
fmt.Println("1")
// start the goroutines
go goroutineC(requestChan)
fmt.Println("2")
go goroutineD(requestChan)
fmt.Println("3")
// sleep for a second to let the goroutines complete
time.Sleep(time.Second)
fmt.Println("10")
}
func goroutineC(requestChan chan chan string) {
// make a new response chan
responseChan := make(chan string)
fmt.Println("4")
// send the responseChan to goRoutineD
requestChan <- responseChan
fmt.Println("5")
// read the response
response := <-responseChan
fmt.Println("8")
fmt.Printf("Response: %v\n", response)
fmt.Println("9")
}
func goroutineD(requestChan chan chan string) {
// read the responseChan from the requestChan
responseChan := <-requestChan
fmt.Println("6")
// send a value down the responseChan
responseChan <- "hello!"
fmt.Println("7")
}
/*输出
1
2
3
4
5
6
7
8
Response: hello!
9
10
*/
五、循环语句
(一)、for循环
1、for init; condition; post { } 和C语言for循环一样
init为赋值,condition为条件语句,post用于变量增减
package main
import "fmt"
func main() {
number := [6]int{1,2,3,4,5,6}
for i := 0;i <6 ;i++{
fmt.Println(number[i])
}
}
2、for condition { } 和C语言while类似
package main
func main() {
var b int = 15
var a int
for a < b{
a++
}
}
3、for range{ }
package main
import "fmt"
func main() {
numbers := [6]int{1, 2, 3, 4, 5, 6}
for i,x:= range numbers {
fmt.Printf("第 %d 位 x 的值 = %d\n", i,x)
}
}
4、for循环嵌套
for [condition | ( init; condition; increment ) | Range]{
for [condition | ( init; condition; increment ) | Range]
{
statement(s);
}
statement(s);}
(二)、break语句
和C语言的break一样
- 用于循环语句中跳出循环,并开始执行循环之后的语句。
- break在switch中用于跳出case语句的作用。
(三)、continue语句
和C语言的continue一样,跳出当前循环执行下一次循环语句。
(四)、goto语句
Go 语言的 goto 语句可以无条件地转移到过程中指定的行。
goto 语句通常与条件语句配合使用。可用来实现条件转移, 构成循环,跳出循环体等功能。
但是,在结构化程序设计中一般不主张使用 goto 语句, 以免造成程序流程的混乱,使理解和调试程序都产生困难。
参考资料:
菜鸟教程Go通道chan用法go chan使用 匿名函数执行