Go运算符、控制语句-DateWhale开源学习

目录

运算符

Go 语言内置的运算符有:

  • 算术运算符
  • 关系运算符
  • 逻辑运算符
  • 位运算符
  • 赋值运算符

假定A值为10B值为20

算数运算符

运算符描述实例
+相加A + B 输出结果 30
-相减A - B输出结果 -10
*相乘A * B 输出结果 200
/相除B / A 输出结果 2
%求余B % A 输出结果0
++自增A++输出结果 11
--自减A-- 输出结果 9

注意: ++(自增)和--(自减)在Go语言中是单独的语句,并不是运算符。

关系运算符

运算符描述
==检查两个值是否相等,如果相等返回True否则返回False
!=检查两个值是否不相等,如果不相等返回True否则返回False
>检查左边值是否大于右边值,如果是返回True否则返回False
<检查左边值是否小于右边值,如果是返回True否则返回False
>=检查左边值是否大于等于右边值,如果是返回True 否则返回 False
<=检查左边值是否小于等于右边值,如果是返回 True 否则返回 False

逻辑运算符

运算符描述
&&逻辑 AND 运算符。 如果两边的操作数都是 True,则条件 True,否则为 False
| |逻辑OR运算符。 如果两边的操作数有一个 True,则条件 True,否则为 False
!逻辑 NOT运算符。 如果条件为 True,则逻辑 NOT条件 False,否则为 True

位运算符

运算符描述
&按位与运算符"&"是双目运算符。 其功能是参与运算的两数各对应的二进位相与。
|按位异或运算符"^"是双目运算符。 其功能是参与运算的两数各对应的二进位相异或,当两对应的二进位相异时,结果为1
^按位异或运算符"^"是双目运算符。 其功能是参与运算的两数各对应的二进位相异或,当两对应的二进位相异时,结果为1
>>右移运算符">>“是双目运算符。右移n位就是除以2n次方。 其功能是把”>>“左边的运算数的各二进位全部右移若干位,”>>"右边的数指定移动的位数。
<<左移运算符"<<“是双目运算符。左移n位就是乘以2n次方。 其功能把”<<“左边的运算数的各二进位全部左移若干位,由”<<"右边的数指定移动的位数,高位丢弃,低位补0

赋值运算符

运算符描述实例
=简单的赋值运算符,将一个表达式的值赋给一个左值C = A + BA + B 表达式结果赋值给 C
+=相加后再赋值C += A等于 C = C + A
-=相减后再赋值C -= A 等于 C = C - A
*=相乘后再赋值C *= A 等于 C = C * A
/=相除后再赋值C /= A 等于 C = C / A
%=求余后再赋值C %= A 等于 C = C % A
<<=左移后赋值C <<= 2 等于 C = C << 2
>>=右移后赋值C >>= 2 等于 C = C >> 2
&=按位与后赋值C &= 2 等于 C = C & 2
^=按位异或后赋值C ^= 2 等于 C = C ^ 2
|=按位或后赋值C |= 2等于 C = C | 2

其他运算符

运算符描述实例
&返回变量存储地址&a; 将给出变量的实际地址。
*指针变量*a; 是一个指针变量

优先级

优先级运算符
5*/%<< >> &&^
4+-|^
3==!=<<=>>=
2&&
1||

控制语句

条件语句

指定一个或多个条件,并通过测试条件是否为true来决定是否执行指定语句,并在条件为false 的情况在执行另外的语句。

if语句
  • if 语句 由一个布尔表达式后紧跟一个或多个语句组成。
  • if 语句 后可以使用可选的else语句, else语句中的表达式在布尔表达式为false时执行。
  • ifelse if语句中可嵌入一个或多个ifelse if语句。
  • 同各类主流语言,不多赘述。但注意,Go 没有三目运算符,所以不支持 ?: 形式的条件判断
package main

import "fmt"

func main() {
   /* 定义局部变量 */
   var a int = 10
   /* 使用 if 语句判断布尔表达式 */
   if a < 20 {
       /* 如果条件为 true 则执行以下语句 */
       fmt.Printf("a 小于 20\n" )
   }
   fmt.Printf("a 的值为 : %d\n", a)
}
switch语句
  • 用于基于不同条件执行不同动作,每一个case分支都是唯一的,从上至下逐一测试,直到匹配为止。
  • 匹配项后面不需要再加break
  • switch默认情况下case最后自带break语句,匹配成功后就不会执行其他case,如果我们需要执行后面的case,可以使用fallthrough
  • fallthrough:强制执行后面的case语句,fallthrough不会判断下一条case的表达式结果是否为 true
switch x.(type){
  case type:
    statement(s);
  case type:
    statement(s);
  default: // 可选
    statement(s);
}

解释:
从第一个判断表达式为truecase开始执行,如果case带有fallthrough,程序会继续执行下一条case,且它不会去判断下一个case的表达式是否为true

  • 支持多条件匹配
  • 不同的case之间不使用break分隔,默认只会执行一个case
  • 如果想要执行多个 case,需要使用fallthrough关键字,也可用break终止
package main

import "fmt"

func main() {
    var x interface{}
    switch i := x.(type) { // 带初始化语句
    case nil:
        fmt.Printf(" x 的类型 :%T\r\n", 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("未知型")
    }
}
select语句
select {
  case communication clause  :
    statement(s);
  case communication clause  :
    statement(s);
  default : // 可选
    statement(s);
}
  • 每个case都必须是一个通信(channel)
  • 所有channel表达式都会被求值
  • 所有被发送的表达式都会被求值
  • 如果任意某个通信可以进行,它就执行,其他被忽略。
  • 如果有多个case都可以运行,Select会随机公平地选出一个执行。其他不会执行。 否则:
    • 如果有default子句,则执行该语句。
    • 如果没有default子句,select将阻塞,直到某个通信可以运行;Go不会重新对channel或值进行求值。
//比如在下面的场景中,使用全局resChan来接受response,如果时间超过3S,resChan中还没有数据返回,则第二条case将执行
var resChan = make(chan int)
// do request
func test() {
    select {
    case data := <-resChan:
        doData(data)
    case <-time.After(time.Second * 3):
        fmt.Println("request time out")
    }
}
func doData(data int) {
    //...
}
//在某些情况下是存在不希望channel缓存满了的需求的,可以用如下方法判断
ch := make (chan int, 5)
//...
data:=0
select {
case ch <- data:
default:
    //做相应操作,比如丢弃data。视需求而定
}
//主线程(协程)中如下:
var shouldQuit=make(chan struct{})
fun main(){
    {
        //loop
    }
    //...out of the loop
    select {
        case <-c.shouldQuit:
            cleanUp()
            return
        default:
        }
    //...
}

//再另外一个协程中,如果运行遇到非法操作或不可处理的错误,就向shouldQuit发送数据通知程序停止运行
close(shouldQuit)

循环语句

for循环
for init; condition; post { } //for
for condition { } //while
for {}
  • init: 一般为赋值表达式,给控制变量赋初值;
  • condition: 关系表达式或逻辑表达式,循环控制条件;
  • post: 一般为赋值表达式,给控制变量增量或减量。
  • for循环的range格式可以对slicemap、数组、字符串等进行迭代循环:
for key, value := range oldMap {
  newMap[key] = value
}
  • 可忽略不想要的返回值,或 “_” 这个特殊变量。
package main

func main() {
    s := "abc"
    // 忽略 2nd value,支持 string/array/slice/map。
    for i := range s {
        println(s[i])
    }
    // 忽略 index。
    for _, c := range s {
        println(c)
    }
    // 忽略全部返回值,仅迭代。
    for range s {

    }

    m := map[string]int{"a": 1, "b": 2}
    // 返回 (key, value)。
    for k, v := range m {
        println(k, v)
    }
}
循环嵌套

循环套循环,格式:

for [condition |  ( init; condition; increment ) | Range] {
 for [condition |  ( init; condition; increment ) | Range] {
   statement(s);
 }
 statement(s);
}
循环控制语句

break语句:

  • 用于循环语句中跳出循环,并开始执行循环之后的语句。
  • breakswitch(开关语句)中在执行一条case 后跳出语句的作用。
  • 在多重循环中,可以用标号label标出想break的循环。

continue语句:跳过当前循环的剩余语句,然后继续进行下一轮循环。

goto:无条件转移到过程中指定行,与条件语句配合,实现条件转移、构成循环、跳出循环体等(不建议用,造成混乱)

forfor range有什么区别?

主要是使用场景不同

for可以:

  • 遍历arrayslice
  • 遍历key为整型递增的map
  • 遍历string

for range可以完成所有for可以做的事情,却能做到for不能做的,包括:

  • 遍历keystring类型的map并同时获取keyvalue
  • 遍历channe
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值