重学Go语言之运算符与控制结构详解

 更新时间:2023年02月28日 14:45:51   作者:程序员读书  
对于任何编程语言来说,运算符和控制结构都算是最基础的知识了,既然是基础,当然非常有必要学习,因此在这篇文章中我们就来讨论一下

运算符

运算符的作用是将操作数组合成表达式,比如下面的代码中,我们通过赋值和加号组成了两个表达式:

var i,j = 1,2
n := i + j

Go的运算符大体分为六种:算术运算符、关系运算符、逻辑运算符、位运算符、赋值运算符和指针运算符。

算术运算符

运算符含义
+加号,除了用于整数,浮点数,复数外,还可以用于字符串的拼接
-减号
*相乘
/相除
%求余,只能用于整数
++自增
--自减
+正数,注意与加号(+)的区别
-负数,注意与减号(-)的区别

用法示例:

var str1 string = "hello"
var str2 string = "world"
str := str1 + str2 //使用+号拼接字符串

i := 3.2 % 2 //报错,只能对整数求余

var n int = 1
n++ 
++n //错误,自增只能加了操作数后面,自减也是同样的

关系运算符

通过逻辑运算符组成的表达式,其计算结果为布尔值,一般用于控制结构的条件部分:

运算符含义
==相等
!=不相等
<=小于或等于
<小于
>=大于或等于

用法示例:

if 2 == (1 + 1) {
	fmt.Println("相等")
}

逻辑运算符

逻辑运算符组成的表达式,其计算结果也同样蝇布尔值,因此也用于控制结构的条件部分:

运算符含义
&&逻辑与
||逻辑或
!逻辑非,一元运算符,具有较高的优先级

位运算符

位运算符只能用于整数

运算符含义
&按位与,两个操作数都1的位置为1,否为0
|按位或,两个操作数只要有1的位置,都为1,否则为0
按位异或,两个操作数都相同为0,否则为1
<<按位左移
>>按位右移
&^按位清空,根据右边操作数为1的位置,将左边对应位置设为0。

用法示例:

fmt.Println(2 & 1) // 00000010 & 00000001,可以看出,没有哪个位置两个操作都为1,因此结果为:00000000
fmt.Println(2 | 1) // 00000010 & 00000001,结果为00000011,也就是3
fmt.Println(2 ^ 1) // 00000010 & 00000001,结果为00000011,也就是3

fmt.Println(1 << 1) //00000001 => 00000010 
fmt.Println(2 >> 1) //00000010 => 00000001

fmt.Println(23 &^ 5) 00010111 &^ 00000101 => 00010010 

赋值运算符

运算符含义
= :=赋值
+=先将左侧与右侧的操作数相加,再赋值给左边的变量
-=先将左侧与右侧的操作数相减,再赋值给左边的变量
*=先将左侧与右侧的操作数相乘,再赋值给左边的变量
/=先将左侧与右侧的操作数相除,再赋值给左边的变量
%=先将左侧与右侧的操作数求余,再赋值给左边的变量
<<=先将左侧的操作数按右侧的操作数向左位移,再将位移结果赋给左边的变量
>>=先将左侧的操作数按右侧的操作数向右位移,再将位移结果赋给左边的变量
&=先将左侧与右侧的操作数进行按位与计算,再将计算结果赋给左边的变量
!=先将左侧与右侧的操作数进行按位或计算,再将计算结果赋给左边的变量
^=先将左侧与右侧的操作数进行按异或计算,再将计算结果赋给左边的变量

指针运算符

运算符含义
&获取变量在内存中的地址
*声明指针变量

运算符的优先级

Go的++与--运算符作用于操作数时形成的是表达式,因此不纳入运算符的优先级中。

在Go语言中,一元运算符具有更高的优先级,如+(正数), -(负数),!(取反),*(指针声明), &(取址)。

而赋值运算符的优先级最低,除了一元运算符以及赋值运算符外,剩下的运算符可以划分为五个优先等级:

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

控制结构

Go的控制结构包括if语句、for语句和switch语句三种。

If

if语句用于判断某个条件是否满足,如果满足,则执行if语句中的代码块,如果不满足,则忽略if语句中的代码块并继续向后执行。

最简单的if语句结构为:

if boolean expression {
	// do something	
}

其中boolean expression为一个可以得到布尔值的表达式,当布尔值为true,会执行if语句中的代码块,如:

if 2 < 10 {
	fmt.Println("ok")
}

除了用于判断的boolean expression外,if也可以包含一个初始化表达式:

if initialization;boolean expression{
	// do something	
}

这种情况下,if会先执行初始化表达式,之后再判断boolean expression得到的布尔是否为true

if i = 10;i < 100 {
	fmt.Println("ok")
}

if语句后面也可以跟上else语句,当然if条件不满足时,会执行else语句中的代码块:

if boolean expression{
	// do something	
}else{
	// do something	
}

用法示例:

if i = 11;i < 11{
	fmt.Println("ok")
}else{
	fmt.Println("bad")
}

如果有多个分支条件判断,可以在if语句后面跟上多个else if 语句,最后可以跟上else语句,当所有条件都不满足时,会执行else语句中的代码块:

if boolean expression1 {
	// do something	
} else if boolean expression2 {
	// do something else	
} else if boolean expression3 {
	// do something else	
}else {
	// catch-all or default
}

For

for语句用于根据条件循环执行其中的代码块,最简单的for语句格式如下:

for condition {
	//do something
}

condition为一个可得到布尔值的表达式,Go语言中并没有while或者do-while语句,因此这种方式的用法接近其他编程语言的while或者do-while语句:

x := 1
for x < 20{
	fmt.Println(x)
	x++
}

如果condition为空,那么此时for则为死循环:

for {
	//do something
}

for最经典,在其他编程语言也有的用法是下面这种形式:

for init statement;condition;post statement{
	//do something
}

用法示例:

for i := 0; i< 10 ;i++ {
	fmt.Println(i)
}

另外,for语句还与关键字range配合,可以用于遍历数组、map和切片等,其作用类似PHP中的foreach语句:

for k,v := range array {
	//do something
}

用法示例:

var a [10]int = [10]int{1,2,3,4,5,6,7,8,9,10}

for index,value := range a {
	fmt.Println(index,value)
}

使用break关键字结束循环

for i := 0; i < 10; i++ {
	if i == 5 {
		break
	}
	fmt.Println(i)
}

使用continue结束跳过单次循环:

for i := 0;i<10;i++{
	if i == 5 {
		continue
	}
	fmt.Println(i)
}

Switch

Switch与if类似,用于根据条件执行满足条件的代码块,但其用法与if不同,switch有几种不同的用法:

第一种使用方法会将switch后面的值与case后面所跟的值进行比较,满足条件则执行case中的代码块,如果都不满足,则执行default中的代码块,其结构如下所示:

switch var1 {
	case val1:
		...
	case val2:
		...
	default:
		...
}

用法示例:

var x = 8
switch x {
	case 8 :
		fmt.Println("8")
	case 9 :
	  fmt.Println("9")
	case 10 :
	  fmt.Println("10")
	default :
		fmt.Println("not found")
}

从上面的例子可以看出,在满足某个条件后,switch执行完该分支就会退出switch语句,不需要像其他编程语言一样使用break来退出switch语句。

如果不想退出switch语句,需要继续让switch语句往下执行,可以在case语句内使用fallthrough关键词:

var x = 8
switch x {
	case 8 :
		fmt.Println("8")
		fallthrough
	case 9 :
	  fmt.Println("9")
	  fallthrough
	case 10 :
	  fmt.Println("10")
	default :
		fmt.Println("not found")
}

上面语句在匹配到case 8:之后,碰到了fallthrough语句,所以继续往下执行,接着继续碰到fallthrough语句,再继续执行,因此三个case代码块都会被执行。

switch的另一种用法是将后面的变量省略,而把执行的判断条件放在case关键词后面,这个用法与if/elseif语句类似:

switch {
	case condition1:
		...
	case condition2:
		...
	default:
		...
}

用法示例:

x := 10
switch {
	case x >= 10:
		fmt.Println("10")
	case x > 11:
		fmt.Println("11")
	default:
		fmt.Println("not found")
}

switch后面可以跟上一个初始化语句:

switch initialization {
	case condition1:
		...
	case condition2:
		...
	default:
		...
}

用法示例:

switch x := 10; {
	case x >= 10:
		fmt.Println("10")
	case x > 11:
		fmt.Println("11")
	default:
		fmt.Println("not found")
}

type-switchswitch语句的另一种用法,主要用于类型断言,后续在学习接口(interface)再介绍

小结

总结一下,这篇文章主要讲了三点:

1.Go支持的运算符:

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

2.运算符的优化级

3.Go支持的控制结构:

  • If语句
  • For语句
  • Switch语句

到此这篇关于重学Go语言之运算符与控制结构详解的文章就介绍到这了,更多相关Go语言 运算符 控制结构内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 详解如何在Go中实现优雅停止

    详解如何在Go中实现优雅停止

    和其他语言相比,Go 中有相同也有不同,相同的是实现思路上和其他语言没啥差异,不同在于 Go 采用的是 goroutine + channel 的并发模型,与传统的进程线程相比,实现细节上存在差异,本文将从实际场景和它的一般实现方式展开,逐步讨论这个话题,需要的朋友可以参考下
    2024-04-04
  • 详解Go语言如何实现并发安全的map

    详解Go语言如何实现并发安全的map

    go语言提供的数据类型中,只有channel是并发安全的,基础map并不是并发安全的,本文为大家整理了三种实现了并发安全的map的方案,有需要的可以参考下
    2023-12-12
  • Golang 中整数转字符串的方法

    Golang 中整数转字符串的方法

    这篇文章主要介绍了Golang 中整数转字符串的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-06-06
  • go切片和指针切片示例详解

    go切片和指针切片示例详解

    在Go语言中,切片(Slice)和指针的切片(即切片中每个元素都是指向某种数据类型的指针)是两个不同的概念,它们各自具有特定的用途和优势,这篇文章主要介绍了go切片和指针切片,需要的朋友可以参考下
    2024-04-04
  • Beego AutoRouter工作原理解析

    Beego AutoRouter工作原理解析

    这篇文章主要为大家介绍了Beego AutoRouter工作原理解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-08-08
  • Golang中时间相关操作合集

    Golang中时间相关操作合集

    这篇文章主要为大家介绍了Golang中的各种时间相关操作,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-09-09
  • golang 中 channel 的详细使用、使用注意事项及死锁问题解析

    golang 中 channel 的详细使用、使用注意事项及死锁问题解析

    这篇文章主要介绍了golang 中 channel 的详细使用、使用注意事项及死锁分析,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-03-03
  • go自动下载所有的依赖包go module使用详解

    go自动下载所有的依赖包go module使用详解

    这篇文章主要介绍了go自动下载所有的依赖包go module使用详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-03-03
  • golang run时报undefined错误的解决

    golang run时报undefined错误的解决

    这篇文章主要介绍了golang run时报undefined错误的解决方案,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-03-03
  • golang中日期操作之日期格式化及日期转换

    golang中日期操作之日期格式化及日期转换

    在编程中,程序员会经常使用到日期相关操作,下面这篇文章主要给大家介绍了关于golang中日期操作之日期格式化及日期转换的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-11-11

最新评论