golang控制语句和运算符

流程控制是每种编程语言控制逻辑走向和执行次序的重要手段,Go语言中最常用的流程控制有 iffor

switchgoto 主要是为了简化代码、降低重复代码而生的结构,属于扩展的流程控制。

一、if else语句(分支结构)

1、if条件判断基本写法

Go 语言中 if 语句的基本写法如下:

if 条件表达式1 {
	分支1
} else if 条件表达式2 {
	分支2
} else {
	分支3
}

当表达式1的结果为 true 时,执行分支1,否则判断表达式2,如果满足则执行分支2,都不满足时,则执行分支3。
if 语句中的 else if 和 else 都是可选的,可以根据实际需要进行选择。

Go 语言规定与 if 匹配的左括号 { 必须与 if 和表达式放在同一行{ 放在其他位置会触发编译错误。示例如下:

func ifDemo1() {
	score := 65
	if score >= 90 {
		fmt.Println("A")
	} else if score >= 80 {
		fmt.Println("B")
	} else if score >= 70 {
		fmt.Println("C")
	}
}

2、if条件判断特殊写法

if 还有一种特殊的写法,可以在 if 表达式之前添加一个执行语句,再根据变量值进行判断。示例如下:

func ifDemo1() {
	if score := 65; score >= 90 {
		fmt.Println("A")
	} else if score >= 80 {
		fmt.Println("B")
	} else if score >= 70 {
		fmt.Println("C")
	}
	// if 语句中的变量 score 的作用域只在 if 条件判断语句中
	// score 变量定义后,可以在 if 条件判断语句中使用,但是在 if 语句外部无法使用。
	fmt.Println(score) // undefined: score
}

这种写法只有在 if 表达式中定义的变量才可以在 if 分支语句中使用,其他地方就不可以使用了。

二、for循环结构

Go 语言中的所有循环类型均可以使用 for 关键字来完成。

1、for循环基本写法

for 循环的基本格式如下:

for 初始语句;条件表达式;结束语句 {
	循环体语句
}

// 示例
func forDemo1() {
	for i := 0; i < 10; i++ {
		fmt.Println(i)
	}
}

条件表达式返回 true 时循环体不停地循环,直到条件表达式返回 false 时自动退出循环。

2、for循环省略初始语句

for 循环的初始语句可以被忽略,但是初始语句后的分号必须要写,例如:

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

3、for循环省略初始语句和结束语句

for 循环的初始语句和结束语句都可以省略,例如:

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

4、无限循环

如果省略循环条件,该循环就不会结束,因此可以用其他方式来结束无限循环,例如使用 break 语句跳出循环。

func forDemo4() {
	for {
		fmt.Println("无限循环")
	}
}

for 循环还可以通过 breakgotoreturnpanic 语句强制退出循环。

5、for range循环

Go 语言中可以使用 for range 遍历数组、切片、字符串、map 及通道(channel)。通过 for range 遍历的返回值有以下规律:

  • 数组、切片、字符串返回索引和值。
  • map 返回键和值。
  • 通道(channel)只返回通道内的值。
// 数组、切片、字符串
for index, value := range slice1 {
	fmt.Println(index, value)
}

// map
for key, value := range map1 {
	fmt.Println(key, value)
}

// 通道(channel)
for value := range channel1 {
	fmt.Println(value)
}

6、continue

在for循环中,当循环遇到continue关键字时,会停止当前循环,开始下一次循环。

func continueDemo1() {
	for i := 0; i < 5; i++ {
		if i == 3 {
			continue // 跳过本次循环,继续下一次循环
		}
		fmt.Println(i)
	}
}
/* Output:
0
1
2
4
*/

// 案例:使用循环输出 1 2 3 4 5 6 8 9 10,即:10以内除7以外的整数。
func continueDemo2() {
	for i := 1; i <= 10; i++ {
		if i == 7 {
			continue
		}
		fmt.Println(i)
	}
}

(1)for循环嵌套

for循环中还可以嵌套for循环,例如:

func continueDemo3() {
	for i := 1; i < 3; i++ {
		// i=1
		// i=2
		for j := 1; j < 5; j++ {
			// j=1/2/3/4
			fmt.Println(i, j)
		}
	}
}

>>> 输出:
1 1
1 2
1 3
1 4
2 1
2 2
2 3
2 4

(2)for循环嵌套 + continue

for循环嵌套 + continue,例如:

func continueDemo4() {
	for i := 1; i < 3; i++ {
		// i=1
		// i=2
		for j := 1; j < 5; j++ {
			// j=1/2/3/4
			if j == 3 {
				continue
			}
			fmt.Println(i, j)
		}
	}
}

>>> 输出:
1 1
1 2
1 4
2 1
2 2
2 4

7、break

在for循环中时,循环中一旦遇到break,跳出循环。

for{
    fmt.Println("王老汉、李老汉、张老汉")
    break
    fmt.Println("alex老婆满身大汗")
}

案例1:猜数字,设定一个理想数字比如:66,一直提示让用户输入数字,如果比66大,则显示猜测的结果大了;如果比66小,则显示猜测的结果小了;只有输入等于66,显示猜测结果正确,然后退出循环。

fmt.Print("开始")
data := 66
for{
    var userInputNumber int
    fmt.Print("请输入数字:")
    fmt.Scanln(&userInputNumber)
    if userInputNumber > data {
        fmt.Println("大了")
    } else if userInputNumber < data {
        fmt.Println("小了")
    } else {
        fmt.Println("恭喜你猜对了")
        break
    }
}
fmt.Print("结束")

案例2:

for i:=1;i<3;i++{
    // i=1
    // i=2
    for j:=1;j<5;j++{
        // j=1/2/3/4
        if j == 3{
            break
        }
        fmt.Println(i,j)
    }
}

>>> 输出:
1 1
1 2
2 1
2 2
for i:=1;i<3;i++{
    // i=1
    // i=2
    for j:=1;j<5;j++{
        // j=1/2/3/4
        if j == 3{
            break
        }
        fmt.Println(i,j)
    }
    break
}

>>> 输出:
1 1
1 2

对for进行打标签,然后通过break和continue就可以实现多层循环的跳出和终止。

f1:
	for i := 1; i < 3; i++ {
		// i=1
		// i=2
		for j := 1; j < 5; j++ {
			// j=1/2/3/4
			if j == 3 {
				continue f1
			}
			fmt.Println(i, j)
		}
	}

>>> 输出:
1 1
1 2
2 1
2 2
f1:
	for i := 1; i < 3; i++ {
		// i=1
		// i=2
		for j := 1; j < 5; j++ {
			// j=1/2/3/4
			if j == 3 {
				break f1
			}
			fmt.Println(i, j)
		}
	}

>>> 输出:
1 1
1 2

三、switch case语句

使用 switch 语句可方便地对大量的值进行条件判断。减少代码量。

func switchDemo1() {
	finger := 3
	switch finger {
	case 1:
		fmt.Println("大拇指")
	case 2:
		fmt.Println("食指")
	case 3:
		fmt.Println("中指")
	case 4:
		fmt.Println("无名指")
	case 5:
		fmt.Println("小拇指")
	default: // 默认情况
		fmt.Println("无效的输入!")
	}
}
/* Output:
中指
*/

1、case后面可以带多个值

case 一次可以判断多个值,使用逗号分隔。

func switchDemo2() {
	num := 5
	switch num {
	case 1, 3, 5, 7, 9:
		fmt.Println("奇数")
	case 2, 4, 6, 8, 10:
		fmt.Println("偶数")
	}
}

/* Output:
奇数
*/

2、case使用表达式

分支可以使用表达式,这时候switch语句后面不需要再跟判断变量。

func switchDemo3() {
	age := 30
	switch {
	case age > 18:
		fmt.Println("成年人")
	case age < 18:
		fmt.Println("未成年人")
	default:
		fmt.Println("未知")
	}
}

/* Output:
成年人
*/

四、goto语句

goto 语句通过标签进行代码间的无条件跳转。

goto 语句可以在快速跳出循环、避免重复退出上有一定的帮助。

Go语言中使用goto语句能简化一些代码的实现过程。例如双层嵌套的for循环要退出时:

func gotoDemo1() {
	// 使用goto语句跳出多层for循环
	for i := 0; i < 10; i++ {
		for j := 0; j < 10; j++ {
			if j == 2 {
				// 设置退出标签
				goto breakTag
			}
			fmt.Printf("%v-%v\n", i, j)
		}
	}
	return
	// 标签
breakTag:
	fmt.Println("结束for循环")
}

/* Output:
0-0
0-1
结束for循环
*/

五、字符串格式化

将数据格式化成为特定格式的字符串时,可以使用字符串格式化。

package main

import "fmt"

func main() {
	var name, address, action string

	fmt.Print("请输入姓名:")
	fmt.Scanln(&name)

	fmt.Print("请输入位置:")
	fmt.Scanln(&address)

	fmt.Print("请输入行为:")
	fmt.Scanln(&action)

	result := fmt.Sprintf("我叫%s,在%s正在干%s", name, address, action)
	//result := "我叫" + name + "在" + address + "干" + action
	fmt.Println(result)
}

六、运算符

Go语言内置的运算符有:算术运算符、关系运算符、逻辑运算符、位运算符、赋值运算符、其他运算符。

1、算术运算符

blockchain

(1)加减乘除求余

// Go语言中的运算符
func main() {
	// 1.算术运算符
	a := 10
	b := 20
	fmt.Println(a + b) // 30
	fmt.Println(a - b) // -10
	fmt.Println(a * b) // 200
	fmt.Println(a / 3) // 3
	fmt.Println(a % 3) // 1
}

(2)自增自减

++-- 在 Go 语言中时单独的语句,不能被赋值给其他变量使用。

Goyu语言中没有++i--i。原因是Go语言中没有前置++--,只有后置++--

package main

import "fmt"

func main() {
	var i int = 1
	var j int = 1
	i++
	j--
	fmt.Println(i, j) // 2, 0
	// ++i     // Go语言中没有++i和--i
}

2、关系运算符

blockchain

func main() {
	fmt.Println(10 > 2)     // true
	fmt.Println(10 != 2)    // true
	fmt.Println(4 <= 3)     // false
}

3、逻辑运算符

blockchain

func main() {
	// && 与运算符,两边都为真才为真
	fmt.Println(10 > 2 && 10 < 2) // false
	fmt.Println(10 > 5 && 3 == 3) // true
	// || 或运算符,两边都为假才为假
	fmt.Println(10 > 2 || 10 < 2)  // true
	fmt.Println(10 > 12 || 3 == 4) // false
	// ! 非运算符,取反
	fmt.Println(!(10 > 2)) // false
	fmt.Println(!(10 < 2)) // true
}

4、位运算符

位运算符对整数在内存中的二进制位进行操作。

blockchain

常见示例:

func main() {
	a := 1      // 0001
	b := 5      // 0101
	// 按位与运算符
	fmt.Println(a & b)     // 0001  => 1
	// 按位或运算符
	fmt.Println(a | b)     // 0101  => 5
	// 按位异或运算符
	fmt.Println(a ^ b)     // 0100  => 4
	// 按位左移运算符
	fmt.Println(a << 2)    // 0100  => 4
	// 按位右移运算符
	fmt.Println(a >> 2)    // 0000  => 0
}

(1)位运算符必知必会概念

  • 计算机中的 存储、运算、网络传输等任何的行为,本质上都是二进制的操作。例如:01010101。

      A				                  B
    hello   -> 0101010010101  ->    hello
    
  • 信息表现形式

    二进制表示:0101010010101   ->  hello
    十进制表示:1921            ->  hello
    
  • 十进制和二进制的转换关系

    十进制 二进制
    0 0
    1 1
    2 10
    3 11
    4 100
    5 101
    6 110
    7 111
    8 1000
    9 1001
    10 1010
    ... ...
    • 二进制转换为十进制

      10101         ->   2**4 + 2**2 + 2**0 => 16 + 4 + 1 => 21
      101010010101  ->   2**11 + 2**9 + ....
      
    • 十进制转换成二进制

      99            -> 64 + 32 + 2 + 1  -> 2**6 + 2**5 + 2**1 + 2*0  -> 1100011
      

(2)位运算

位运算指的是二进制之间的运算:

// 1.按位进行与运算(全为1,才得1)
r1 := 5 & 99
5  -> 0000101
99 -> 1100011
      0000001   -> 1

// 2.按位进行或运算(只要有1,就得1)
r2 := 5 | 99
5  -> 0000101
99 -> 1100011
      1100111   -> 2**6 + 2**5 + 2**2 + 2**1 + 2**0 = 64 + 32 + 4 + 2 + 1 = 103

// 3.按位进行异或运算(上下不同,就得1)
r3 := 5 ^ 99
5  -> 0000101
99 -> 1100011
      1100110   -> 2**6 + 2**5 + 2**2 + 2**1 = 64 + 32 + 4 + 2 = 102

// 4.按位向左移动
r4 := 5 << 2
        5  -> 101
向左移动2位  -> 10100  -> 2**4 + 2**2 = 16 + 4 = 20

// 5.按位向右移动
r5 := 5 >> 1
        5  -> 101
向右移动1位  -> 10  -> 2**1 = 2

// 6.比较清除   // 以前面的值为基准,让前面的和后面的值的二进制位进行比较,如果两个位置都是1,则讲前面的值的那个位置置0
r6 := 5 &^ 99
5  -> 0000101
99 -> 1100011
      0000100     -> 2**2 = 4

5、赋值运算符

blockchain

赋值运算符案例:

func main() {
	// 赋值运算符
	// += -= *= /= %= <<= >>= &= |= ^=
	var a int = 5
	a += 5         // a = a + 5
	fmt.Println(a) // 10
	var b int = 5  // 101

	// 左移2位赋值给b
	b <<= 2        // 10100  => 20
	fmt.Println(b) // 20

	// 按位与后赋值
	var c int = 5 // 101
	c &= 3        // 101 & 011 => 001 => 1
	fmt.Println(c)
}

6、运算符的优先级

Precedence    Operator
    5             *  /  %  <<  >>  &  &^
    4             +  -  |  ^
    3             ==  !=  <  <=  >  >=
    2             &&
    1             ||
v1 := 3 + 2 * 2
v2 := 8 == 5 & 99

注意:不要想办法去记住他,使用括号。

参考地址:

叮嘱:不要太过于用心去背、记,主要认识即可。优先级记不住就用括号。

今日作业

  1. 猜年龄游戏,要求:允许用户最多尝试3次,3次都没猜对的话,就直接退出,如果猜对了,打印恭喜信息并退出。
  2. 实现用户登录系统,并且要支持连续3次输错之后直接退出,并且在每次输错误时显示剩余错误次数(提示:使⽤字符串格式化)。
posted @ 2023-05-05 23:01  休耕  阅读(65)  评论(0编辑  收藏  举报