青训营第四节GO语言基础总结 | 青训营

99 阅读23分钟

一、概述­

­●什么是程序:

程序:为了让计算机执行某些操作或解决某个问题而编写的一系列有序指令的集合

­●Go语言 是区块链最主流的编程语言

同时也是当前最具发展潜力的语言

­●Go语言是Google公司创造的语言,也是Google主推的语言。

­●Google创造Golang的原因

●Golang的语言的特点

    Go语言保证了既能到达静态编译语言的安全和性能,又达到了动态语言开发维护的高效率,使用一个表达式来形容Go语言: Go=C + Python,说明Go语言既有C静态语言程序的运行速度,又能达到Python动态语言的快速开发。

1 ) 从C语言中继承了很多理念,包括表达式语法,控制结构,基础数据类型,调用参数传值,指针等等,也保留了和C语言一样的编译执行方式及弱化的指针

2 ) 引入包的概念,用于组织程序结构,Go语言的一个文件都要归属于一个包,而不能单独存在。 3 ) 垃圾回收机制,内存自动回收,不需开发人员管理

4 ) 天然并发(重要特点) (1)从语言层面支持并发,实现简单 (2) goroutine,轻量级线程,可实现大并发处理,高效利用多核。

    (3)基于CPS并发模型(Communicating Sequential Processes )实现

5 ) 吸收了管道通信机制,形成Go语言特有的管道channel通过管道channel ,可以实现不同的goroute之间的相互通信。 6 ) 函数可以返回多个值

7 ) 新的创新:比如切片 slice 、 延时执行 defer等

二、Windows下搭建Go开发环境 1、SDK的全称(Software Development Kit 软件开发工具包)

2、SDK是提供给开发人员使用的,其中包含了对应开发语言的工具包。

SDK下载地址:Downloads - The Go Programming Language

3、解压后的 go目录就是SDK

bin文件夹存放 go的指令 go / godoc / gofmt

src文件夹放 go的源代码

4、go.exe 使用go.exe可以编译和运行我们的go源码

5、如何测试go的SDK安装成功 go version

6、配置环境变量

三、Go语言快速开发入门 一、

1)go文件的后缀是.go

2)package main

表示该hello.go 文件所在的包是main,在go中,每个文件都必须归属于一个包。

3)import "fmt"

表示:引入一个包,包名fmt,引入该包后,就可以使用fmt包的函数,比如:fmt.Println

4) func main(){

}

func 是一个关键字,表示一个函数

main是函数名,是一个主函数,即我们程序的入口

5)fmt.Println("hello")

表示调用 fmt包的函数 Println输出"hello,world"

二、

通过go build 命令对该go文件进行编译,生成 .exe文件

三、

运行hello.exe文件即可

注意:通过 go run 命令可以直接运行hello.go 程序 [类似执行一个脚本文件的形式]

四、Golang执行流程分析 如果是对源码编译后,再执行,Go的执行流程如下图

如果对源码直接执行 go run 源码,Go的执行流程如下图

两种执行流程的方式区别

    1)如果我们先编译生成了可执行文件,那么我们可以将该可执行文件拷贝到没有go开发环境的机器上,仍然可以运行
    2)如果我们是直接 go run go源代码,那么如果要在另外一个机器上这么运行,也需要go开发环境,否则无法执行。
    3)在编译时,编译器会将程序运行依赖的库文件包含在可执行文件中,所以,可执行文件变大了很多。

Go语言程序开发的注意事项

  1. Go源文件以“go”为扩展名。

2)Go应用程序的执行入口是mainO函数。这个是和其它编程语言(比如java/c)

3)Go语言严格区分大小写。

  1. Go方法由一条条语句构成,每个语句后不需要分号(Go语言会在每行后自动加分号),这也体现出Golang 的简洁性。

5)Go编译器是一行行进行编译的,因此我们一行就写一条语句,不能把多条语句写在同一个,否则报错

6)go语言定义的变量或者import的包如果没有使用到,代码不能编译通过。

7)大括号都是成对出现的,缺一不可。

Go语言的转义字符 1) \t : 表示一个制表符,通常使用它可以排版。

2)\n :换行符

3)\ :一个\

  1. " : 一个 "

  2. \r : 一个回车 fmt.Println("12346577\r758")

从当前行的最前面开始输出,覆盖掉以前内容

效果如下

小作业 实现下图

package main

import "fmt" func main(){ fmt.Println("姓名\t年龄\t籍贯\t住址\njohn\t12\t河北\t北京") } Go格式化指令 gofmt -w xxx.go

该指令可以将格式化后的内容重写写入到文件。当程序员重新打开文件时,就会看到新的格式化后的文件

运算符两边习惯性各加一个空格。比如 : 2 + 4 * 5

代码风格 左边的写法是正确的 右边的写法是错误的

一行最长不超过80个字符,超过的请使用换行展示,尽量保持格式优雅

Golang 官方编程指南 说明: Golang 官方网站 golang.org , 需要特殊上网

官方标准库API文档,golang.org/pkg

国内API文档 studygolang.com/pkgdoc

api : application program interface:应用程序编程接口。

就是我们Go的各个包的各个函数

相对路径:从当前位置开始定位,去找对应的目录

绝对路径:从当前盘的最上面开始定位

五、变量 变量都是其程序的基本组成单位

变量相当于内存中一个数据存储空间的表示

变量使用的基本步骤 1)声明变量(也有人叫:定义变量)

2)非变量赋值

3)使用变量

package main import "fmt"

func main() { var i int i = 10 fmt.Println("i=", i) }

Golang变量使用的三种方式 1、指定变量类型,声明后若不赋值,使用默认值

package main import "fmt"

func main() { var i int fmt.Println("i=", i) }

2、根据值自行判定变量类型(类型推导)

package main import "fmt"

func main() { var num = 10.11 fmt.Println("num=", num) }

3、省略var,【注意 := 左侧的变量不应该是已经声明过的,否则会导致编译错误】

package main import "fmt"

func main() { name := "tom" fmt.Println("name=", name) }

4、多变量声明

在编程中,有时我们需要一次性声明多个变量,Golang也提供这样的语法

package main import "fmt"

func main() { //方式1 var n1, n2, n3 int fmt.Println("n1=", n1, "n2=", n2, "n3=", n3) //方式2 一次性声明多个变量的方式2 var n1, name , n3 = 100, "tom", 888 fmt.Println("n1=",n1, "name=", name, "n3=", n3) //一次性声明多个变量的方式3,同样可以使用类型推导
n1, name , n3 := 100, "tom~~", 888 fmt.Println("n1=",n1, "name=", name, "n3=", n3) }

如何一次性声明多个全局变量【在go中函数外部定义变量就是全局变量】

package main import "fmt"

//定义全局变量 var n1 = 100 var n2 = 200 var name = "jack" //上面的声明方式,也可以改成一次声明 var( n3 = 300 n4 = 900 name2 = "mary" )

func main(){ fmt.Println("n1=",n1, "name=", name, "n2=", n2) fmt.Println("n3=",n3, "name2=", name2, "n4=", n4) }

5、该区域的数据值可以在同一类型范围内不断变化(重点)

package main import "fmt"

//变量使用的注意事项 func main() { //该区域的数据值可以在同一类型范围内不断变化 var i int = 10 i = 30 i = 50 fmt.Println("i=", i) i = 1.2 //[会报错,i为int,原因是不能改变数据类型] } 6、变量在同一个作用域(在一个函数或者在代码块)内不能重名

//变量在同一个作用域(在一个函数或者在代码块)内不能重名 如下:
var i int = 59
i := 99

7、变量三要素 变量=变量名+值+数据类型

8、Golang的变量如果没有赋初值,编译器会使用默认值。

比如int默认值 0

String默认值为空串

小数默认为 0

六、程序中 + 号的使用 1)当左右两边都是数值型时,则做加法运算

2)当左右两边都是字符串,则做字符串拼接

package main import "fmt"

func main(){

var i = 1
var j = 2
var r = i + j //做加法运算
fmt.Println("r=", r)

var str1 = "hello"
var str2 = "world"
var res = str1 + str2 //做拼接操作
fmt.Println("res=", res)

}

变量的数据类型

七、整数类型

注: uint8的范围(0-255),其他的uint16,uint32依此类推

整型的使用细节

  1. Golang各整数类型分:有符号和无符号,int uint 的大小和系统有关。

2)Golang的整型默认声明为int型

3)如何在程序查看某个变量的字节大小和数据类型

  1. Golang程序中整型变量在使用时,遵守保小不保大的原则,

     即:在保证程序正确运行下,尽量使用占用空间小的数据类型。【如:年龄】
    
  2. bit:计算机中的最小存储单位。byte:计算机中基本存储单元。

八、浮点类型

1)关于浮点数在机器中存放形式的简单说明,浮点数=符号位+指数位+尾数位3.56

2)尾数部分可能丢失,造成精度损失。 -123.0000901

说明:float64的精度比float32的要准确

如果我们要保存一个精度高的数,则应该选用float64

3)浮点型的存储分为三部分: 符号位 + 指数位 + 尾数位 在存储过程中,精度会有丢失

浮点型使用细节 1)Golang浮点类型有固定的范围和字段长度,不受具体OS(操作系统)的影响。

2)Golang的浮点型默认声明为 float64 类型。 【%T】

3)浮点型常量有两种表示形式

十进制数形式 如: 5.12 / .512【效果等于0.512】(必须有小数点)

科学计数法形式 如:5.1234e2 = 5.12 * 10 的2次方 5.12E-2 = 5.12/10的2次方

4)通常情况下,应使用float64,因为它比float32更精确。【开发中,推荐使用float64】

九、字符类型(char) Golang中没有专门的字符类型,如果要存储单个字符(字母),一般使用byte来保存。

  字符串就是一串固定长度的字符连接起来的字符序列。Go的字符串是由单个字节连接起来的。也就是说对于传统的字符串是由字符组成的,而Go的字符串不同,它是由字节组成的。

package main import ( "fmt" )

func main(){ var c1 byte = 'a' var c2 byte = '1' //字符的1

//当我们直接输出byte值,就是输出了的对应的字符的码值
fmt.Println("c1=", c1)
fmt.Println("c2=", c2)
//如果我们希望输出对应字符,需要使用格式化输出
fmt.Printf("c1=%c c2=%c\n", c1, c2)//注意此处为Printf

//var c3 byte = '北' //overflow 溢出
var c3 int = '北' //overflow 溢出
fmt.Printf("c3=%c c3对应码值=%d", c3, c3)

}

1)如果我们保存的字符在ASCII表的,比如[0-1,a-z,A-Z...]直接可以保存到byte

2)如果我们保存的字符对应码值大于255,这时我们可以考虑使用int类型保存

3)如果我们需要安装字符的方式输出,这时我们需要格式化输出,即 fmt.Printf("%c", c1)...

4)字符类型是可以进行运算的,相当于一个整数,因为它都对应有Unicode码。

注:Go语言的字符使用UTF-8编码 英文字母-1个字节 汉字-3个字节

Go语言的编码都统一成了utf-8。非常的方便,很统一,再也没有编码乱码的困扰了

存取过程 存储:字符--->对应码值--->二进制--->存储

读取: 二进制--->码值--->字符--->读取

十、布尔类型:bool 1)bool类型占1个字节

package main import ( "fmt" "unsafe" )

func main() { var b = false fmt.Println("b=", b) fmt.Println("b 的占用空间 =", unsafe.Sizeof(b) )

}

2)boolean类型适于逻辑运算,一般用于程序流程控制

if条件控制语句:

for循环控制语句:

3)不可以0或非0的整数替代false和true,这点和C语言不同 十一、字符串类型:String package main import ( "fmt" )

func main() { var address string = "你好世界!" fmt.Println(address) }

注意事项 1、字符串一旦赋值了,字符串就不能修改了,在Go中字符串是不可变的

2、字符串的两种表示形式

(1)双引号,会识别转义字符

(2)反引号,以字符串的原生形式输出,包括换行和特殊字符,可以实现防止攻击、输出源代码等效果 【....

基本数据类型默认值

十二、基本数据类型的转换 Go在不同类型的变量之间赋值时需要显式转换(强制转换),而就是说Golang中数据类型不能自动转换

基本语法 表达式T(v)将值v转换为类型T

T:就是数据类型,比如 int32 , int64, float32等等

v:就是需要转换的变量

package main import ( "fmt" )

func main(){ var i int32 = 100 //将i => float var n1 float32 = float32(i) var n2 int8 = int8(i) var n3 int64 = int64(i)

fmt.Printf("i=%v n1=%v n2=%v n3=%v", i, n1, n2, n3)

}

注意 1、Go中,数据类型的转换可以是从 表示范围小-->表示范围大,也可以 范围大--->范围小

2、被转换的是变量存储的数据(即值),变量本身的数据类型并没有变化

3、在转换中,比如将int64 转成 int8 【-128----127】,编译时不会报错,只是转换的结果是按溢出处理,和我们希望的结果不一样.因此在转换时,需要考虑范围

package main import( "fmt" ) func main() { var n1 int32 = 12 var n2 int64 var n3 int8

n2 = n1 + 20  //int32 ---> int64 报错 改正【int64(n1) + 20n3 = n1 + 20  //int32 ---> int8 报错 改正【int8(n1) + 20】
fmt.Println("n2=", n2, "n3=", n3)

} package main import( "fmt" ) func main() { var n1 int32 = 12 var n3 int8 var n4 int8 n4 = int8(n1) + 127 //【编译通过,但是 结果 不是127+12,按溢出处理】 n3 = int8(n1) + 128 //【编译不通过】 fmt.Println(n4) } 上述代码结果为 n4 = -117 n3由于编译不通过无法运行代码

如何忽略包

十三、基本数据类型和string的转换 基本类型转string类型 方式1:fmt.Sprintf("%参数", 表达式)

package main import ( "fmt" )

func main(){ var num1 int = 99 var num2 float64 = 23.456 var b bool = true var a bool = true var myChar byte = 'h' var str string //空的str

//使用第一种方式来转换 fmt.Sprintf方法

str = fmt.Sprintf("%d", num1)
fmt.Printf("str type %T str=%v\n", str, str)

str = fmt.Sprintf("%f", num2)
fmt.Printf("str type %T str=%v\n", str, str)

str = fmt.Sprintf("%t", b)
fmt.Printf("str type %T str=%v\n", str, str)

str = fmt.Sprintf("%t", a)
fmt.Printf("str type %T str=%q\n", str, str)

str = fmt.Sprintf("%c", myChar)
fmt.Printf("str type %T str=%q\n", str, str)

}

%v 值的默认格式表示

%t 单词true或false

%d 表示为十进制

%f 有小数部分但无指数部分,如123.456

%q 该值对应的单引号括起来的go语法字符字面值,必须时会采用安全的转义表示

方法2:使用strconv包的函数

package main import ( "fmt" "strconv" )

func main() { var str string var num3 int = 99 var num4 float64 = 23.456 var b2 bool = true

str = strconv.FormatInt(int64(num3), 10)
fmt.Printf("str type %T str=%q\n", str, str)
//str = strconv.FormatFloat(num4, 'f', 10, 64)
//说明:'f' 格式 10 :表示小数位保留1064:表示这个小数是float64
str = strconv.FormatFloat(num4, 'f', 10, 64)
fmt.Printf("str type %T str=%q\n", str, str)

str = strconv.FormatBool(b2)
fmt.Printf("str type %T str=%q\n", str, str)

}

string类型转基本数据类型 使用strconv包的函数

package main import ( "fmt" "strconv" )

func main() { var str string = "true" var b bool //b , _ = strconv.ParseBool(str) //说明 //1.strconv.ParseBool(str) 函数会返回两个值 (value bool, err error) //2.因为我只想获取到 value bool , 不想获取 err 所以我使用 _ 忽略 b , _ = strconv.ParseBool(str) fmt.Printf("b type %T b=%v\n", b, b)

var str2 string = "1234567890"
var n1 int64
var n2 int
n1, _ = strconv.ParseInt(str2, 10, 64)
n2 = int(n1)
fmt.Printf("n1 type %T n1=%v\n", n1, n1)
fmt.Printf("n2 type %T n1=%v\n", n2, n2)

var str3 string = "123.456"
var f1 float64
f1, _ = strconv.ParseFloat(str3, 64)
fmt.Printf("f1 type %T f1=%v\n", f1, f1)

}

因为返回的是int64或者float64,如希望要得到int32,float32等如下处理:

//如果希望将str->int32的可以这样处理 var num5 int32 num5 = int32(num) 注意事项 在将String 类型转成 基本数据类型时,要确保String类型能够转成有效的数据,比如我们可以把"123”,转成一个整数,但是不能把“hello”转成一个整数,如果这样做,Golang直接将其转成0 ,其它类型也是一样的道理, float => 0 bool => false

十四、指针 1、基本数据类型,变量存的就是值,也叫值类型

    分析一下基本数据类型在内存的布局

2、获取变量的地址, 用&,比如: var num int, 获取num的地址:&num

3、指针类型,指针变量存的是一个地址,这个地址指向的空间存的才是值

比如: var ptr *int = &num

package main import ( "fmt" )

//演示golang中指针类型 func main() { //基本数据类型在内存布局 var i int = 10 // i 的地址是什么,&i fmt.Println("i的地址=", &i)

//下面的 var ptr *int = &i
//1. ptr 是一个指针变量
//2. ptr 的类型 *int
//3. ptr 本身的值&i
var ptr *int = &i
fmt.Printf("ptr=%v\n", ptr)
fmt.Printf("ptr 的地址=%v\n", &ptr)
fmt.Printf("ptr 指向的值=%v\n", *ptr)

}

4、获取指针类型所指向的值,使用:*,比如: var ptr int,使用ptr获取ptr指向的值

5、

println和printf的区别 Println:打印字符串、变量;

Printf:打印需要格式化的字符串,可以输出字符串类型的变量;不可以输出变量和整型;

简要概括 当需要格式化输出信息时,一般选择Printf,其余使用Println。

课堂作业

1)写一个程序,获取一个int变量num的地址,并显示到终端

2)将num的地址赋给指针ptr,并通过ptr去修改num的值

package main import( "fmt" )

func main(){ var num int = 100 fmt.Printf("num= %v\n", &num)

var ptr *int
ptr = &num
*ptr = 10 //在这里修改时,会到num的值变化
fmt.Println("num= ", num)

}

指针的使用细节 1)值类型,都有对应的指针类型,形式为 *数据类型,比如 int 的对应的指针就是 *int , float32对应的指针类型就是 *float32,依次类推。 2)值类型包括:基本数据类型 int系列, float系列, bool, string 、数组 和 结构体struct

十五、值类型和引用类型 常见的值类型和引用类型 1)值类型:基本数据类型 int系列, float系列, bool, string、数组 和 结构体struct

2)引用类型:指针、slice切片、map、管道chan、interface 等都是引用类型

值类型和引用类型使用特点: 1)值类型:变量直接存储值,内存通常在栈中分配

2)引用类型:变量存储的是一个地址,这个地址对应的空间才真正存储数据(值),内存通常在堆上分配,当没有任何变量引用这个地址时,该地址对应的数据空间就成为一个垃圾,由GC来回收。

3)内存的栈区和堆区示意图

十六、标识符的命名规范(重点) Golang对各种变量、方法、函数等命名时使用的字符序列称为标识符

凡是自己可以起名字的地方都叫标识符

系统保留关键字

预定标识符

十七、标识符命名注意事项(重点) 1、变量名、函数名、常量名:采用驼峰法

2、如果变量名、函数名、常量名首字母大写,则可以被其他的包访间;如果首字母小写,则只能在本包中使用(注:可以简单的理解成,首字母大写是公有的(public),首字母小写是私有的(private)),在golang中没有public , private 等关键字。

注意事项

当GO引入包报错 PACKAGE ... IS NOT IN GOROOT

首先查看go环境变量配置

go env 查看GO111MODULE是否设置为off

若没有设置则输入以下代码

go env -w GO111MODULE=off 使用案例: 在main文件夹下创建main.go

package main import( "fmt" //为了使用utils.go文件的变量或者函数,我们需要先引入该model包 "go_code/project02/model" ) func main() {

fmt.Println(model.HeroName)

} 在model文件夹下创建utils.go

package model

var HeroName string = "百特曼" 十八、运算符 1、算数运算符

在golang中,++ 和 -- 只能独立使用 package main import ( "fmt" )

func main() { var i int = 10 i++ fmt.Println("i=", i) } Golang的 ++ 和 -- 只能写在变量的后面,不能写在变量的前面,即:只有a++ a--没有++a --a

2、关系运算符(比较运算符) 1)关系运算符的结果都是bool型,也就是要么是true,要么是false

2)关系表达式 经常用在 if结构的条件中或循环结构的条件中

细节说明

3、逻辑运算符 用于连接多个条件(一般来讲就是关系表达式),最终的结果也就是一个bool值

4、赋值运算符 赋值运算符就是将某个运算后的值,赋给指定的变量。

赋值运算符的特点 赋值运算符的左边 只能是变量,

右边 可以是变量、表达式、常量值

5、运算符优先级

6、位运算符

7、其他运算符

Go语言明确不支持三元运算符

若要实现三元运算符则用 if else方式解决

//传统的三元运算 n = i > j ? i : j //如果成立则返回i这个值,不成立则返回j这个值 Go要实现三元运算需要使用下面这种方法

package main import ( "fmt" ) func main() { var n int var i int = 10 var j int = 12

if i > j {
	n = i 
} else {
	n = j
}
fmt.Println("n=", n)

}

十九、键盘输入语句 编程步骤:1、导入fmt包 2、调用fmt包的 fmt.Scanln() 或者 fmt.Scanf()

特别注意 Scanln 会在换行时才停止扫描。最后一个条目后必须有换行或者到达结束位置

1)使用 fmt.Scanln() 获取 package main import ( "fmt" )

func main() { //方式1 fmt.Scanln var name string var age byte var sal float32 var isPass bool fmt.Println("请输入姓名") //程序会停止在这,等待用户输入,并回车 fmt.Scanln(&name)

fmt.Println("请输入年龄")
fmt.Scanln(&age)

fmt.Println("请输入薪水")
fmt.Scanln(&sal)

fmt.Println("请输入是否通过考试")
fmt.Scanln(&isPass)

fmt.Printf("名字是 %v 年龄是 %v 薪水是 %v 是否通过考试 %v \n", name, age, sal, isPass)

}

2)fmt.Scanf() 获取 package main import ( "fmt" )

func main() { //方式2 fmt.Scanf,可以按指定的格式输入 var name string var age byte var sal float32 var isPass bool fmt.Println("请输入您的姓名、年龄、薪水、是否通过考试,使用空格隔开") fmt.Scanf("%s %d %f %t", &name, &age, &sal, &isPass) fmt.Printf("名字是 %v 年龄是 %v 薪水是 %v 是否通过考试 %v \n", name, age, sal, isPass) }

二十、进制转换 1) 二进制转换成十进制 1011 = 1 * 2^0 + 1 * 2^1 + 0 * 2^2 + 1 * 2^3 = 1 + 2 + 0 + 8 = 11

2)八进制转换成十进制 0123 = 3 * 8^0 + 2 * 8^1 + 1 * 8^2 + 0 * 8^3 = 3 + 16 + 64 = 83

3)十六进制转换成十进制 0x34A = 10 * 16^0 + 4 * 16^1 + 3 * 16^2 = 10 + 64 + 768 = 842

4)十进制转换成二进制 将该数不断除以2,直到商为0为止,将每步得到的余数倒过来,就是对应的二进制

例:将56转化为二进制 = 111000

5)十进制转换成八进制 156转化为八进制 = 234

6)十进制转换成十六进制 356转化为十六进制 = 0x164

7)二进制转八进制 每三位一组 (从低位开始组合)

11 010 101 = 011 010 101 = 3 2 5 = 325

8)二进制转十六进制 每四位一组 (从低位开始组合)

1101 0101 = 13 5 = D 5 = 0xD5

9)八进制转二进制 0237 = 0 2 3 7 = 000 010 011 111 = 10 011 111 = 10011111

10)十六进制转二进制 0x237 = 2 3 7 = 0010 0011 0111 = 10 0011 0111 = 1000110111

二十一、位运算 1、原码 反码 补码 1)二进制最高位是符号位: 0为正数 , 1 为负数

    2)正数的 原、 反、 补 都一样

    3)负数的反码 = 符号位不变 ,其余取反 (0->1,1->0)

    4)负数的补码 = 反码 + 1

   例: 1 =====> [0000 0001]

           -1 =====>原码[1000 0001] 反码 [1111 1110] 补码[1111 1111]

    5)0的 反码 补码 都是 0

    6)计算机运算的时候,都是以补码的方式来运算的

2、位运算和移位运算 Golang中有3个位运算 按位与 & : 两位全为 1 ,结果为1,否则为0

按位或 | : 两位有一个为 1 ,结果为1 ,否则为0

按位异或 ^ : 两位 一个为0,一个为1,结果为1,否则为0

例:

Golang中有2个移位运算 右移运算符 >> :低位溢出,符号位不变,并用符号位补溢出的高位

左移运算符 << : 符号位不变,低位补0

a := 1 >> 2 【右移两位】------------- 0000 0001 => 0000 0000(01) => 0000 0000 = 0

c := 1 << 2 【左移两位】------------- 0000 0001 => 0000 0001 00 =>00 0000 0100 = 4

---------<分割线:以上为基础知识>----------- 二十二、程序流程控制 1、单分支控制

2、双分支控制

3、多分支控制

对上面基本语法的说明 1)多分支的判断流程如下: (1)先判断条件表达式1是否成立,如果为真,就执行代码块1 (2)如果条件表达式1如果为假,就去判断条件表达式2是否成立,如果条件表达式2为真,就执行代码块2 (3)依次类推. (4)如果所有的条件表达式不成立,则执行else 的语句块。

  1. else不是必须的。 3)多分支只能有一个执行入口。

注意: 在golang语句中 if 后面必须是条件语句 不能是赋值语句

下面这种写法会报错

练习: 练习1

package main

import ( "fmt" "math" )

func main() { var a float64 var b float64 var c float64 var x1 float64 var x2 float64

fmt.Println("输入a")
fmt.Scanln(&a)
fmt.Println("输入b")
fmt.Scanln(&b)
fmt.Println("输入c")
fmt.Scanln(&c)

var flag float64 = b*b - 4*a*c

if flag > 0 {
	x1 = (-b + math.Sqrt(flag)) / 2 * a
	x2 = (-b - math.Sqrt(flag)) / 2 * a
	fmt.Printf("两个解,分别是 x1=%v x2=%v", x1, x2)
} else if flag == 0 {
	x1 = (-b + math.Sqrt(flag)) / 2 * a
	fmt.Printf("一个解,x=%v", x1)
} else {
	fmt.Println("无解")
}

}

练习2

package main

import ( "fmt" )

func main() { var height int32 var money float32 var handsome bool

fmt.Println("身高: 财富(单位万): 帅吗:")
fmt.Scanf("%d %f %t", &height, &money, &handsome)

if height >= 180 && money >= 1000 && handsome == true {
	fmt.Println("我一定要嫁给他")
} else if height >= 180 || money >= 1000 || handsome == true {
	fmt.Println("嫁吧,比上不足,比下有余")
} else {
	fmt.Println("不嫁")
}

}

4、嵌套分支

注:嵌套分支不宜过多,最多建议控制在3层

案例1

package main

import ( "fmt" )

func main() { var second float64 var gender string

fmt.Println("请输入成绩")
fmt.Scanln(&second)
fmt.Println("请输入性别")
fmt.Scanln(&gender)

if second <= 8 {
	if gender == "男" {
		fmt.Println("晋级男子组决赛")
	} else {
		fmt.Println("晋级女子组决赛")
	}
} else {
	fmt.Println("淘汰")
}

}