文章目录

  • 三、运算符
  • (一)、算术运算符
  • (二)、关系运算符
  • (三)、逻辑运算符
  • (四)、位运算符
  • (五)、赋值运算符
  • (六)、其他运算符
  • (七)、运算符优先级
  • 四、条件语句
  • (一)、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 会随机公平地选出一个执行。其他不会执行。
    否则:
  1. 如果有 default 子句,则执行该语句。
  2. 如果没有 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一样

  1. 用于循环语句中跳出循环,并开始执行循环之后的语句。
  2. break在switch中用于跳出case语句的作用。

(三)、continue语句

和C语言的continue一样,跳出当前循环执行下一次循环语句。

(四)、goto语句

Go 语言的 goto 语句可以无条件地转移到过程中指定的行。
goto 语句通常与条件语句配合使用。可用来实现条件转移, 构成循环,跳出循环体等功能。
但是,在结构化程序设计中一般不主张使用 goto 语句, 以免造成程序流程的混乱,使理解和调试程序都产生困难。

参考资料:
菜鸟教程Go通道chan用法go chan使用 匿名函数执行