·go常用命令
直接在终端中输入 go help 即可显示所有的 go 命令以及相应命令功能简介,主要有下面这些:
build: 编译包和依赖
clean: 移除对象文件
doc: 显示包或者符号的文档
env: 打印go的环境信息
bug: 启动错误报告
fix: 运行go tool fix
fmt: 运行gofmt进行格式化
generate: processing source生成go文件
get:下载并安装包和依赖
install:编译并安装包和依赖
list:列出包
run:编译并运行go程序
test:运行测试
tool:运行go提供的工具version:显示go的版本vet:运行go tool vet
·快速入门
package main
import "fmt"
func main(){
fmt.Println("sadas")
}
- go 文件的后缀是 .go
- package main 表示该 hello.go 文件所在的包是 main, 在 go 中,每个文件都必须归属于一个包。
- import “fmt” 表示:引入一个包,包名 fmt, 引入该包后,就可以使用 fmt 包的函数,比如:fmt.Println
- func main() { }
func 是一个关键字,表示一个函数。 main 是函数名,是一个主函数,即我们程序的入口。
- fmt.Println(“hello”) 表示调用 fmt 包的函数 Println
·通过 go build 命令对该 go 文件进行编译,生成 .exe 文件.
·运行 hello.exe
运行 hello.exe 文件即可
·注意:通过 go run 命令可以直接运行 hello.go 程序 [类似执行一个脚本文件的形式
·Golang 执行流程分析 Ø
如果是对源码编译后,再执行,Go 的执行流程如下图 Ø
如果我们是对源码直接 执行 go run 源码,Go 的执行流程如下图 Ø
Ø 两种执行流程的方式区别
1) 如果我们先编译生成了可执行文件,那么我们可以将该可执行文件拷贝到没有 go 开发环境的机
器上,仍然可以运行
2) 如果我们是直接 go run go 源代码,那么如果要在另外一个机器上这么运行,也需要 go 开发
环境,否则无法执行。
3) 在编译时,编译器会将程序运行依赖的库文件包含在可执行文件中,所以,可执行文件变大了
很多。
第 2 章 Golang 的概述
·Golang 的语言的特点
Ø 简介:
Go 语言保证了既能到达静态编译语言的安全和性能,又达到了动态语言开发维护的高效率
,使用一个表达式来形容 Go 语言:Go = C + Python , 说明 Go 语言既有 C 静态语言程
序的运行速度,又能达到 Python 动态语言的快速开发。
1) 从 C 语言中继承了很多理念,包括表达式语法,控制结构,基础数据类型,调用参数传值,指针等
等,也保留了和 C 语言一样的编译执行方式及弱化的指针
举一个案例(体验):
//go 语言的指针的使用特点(体验)
func testPtr(num *int) {
*num = 20
}
- 引入包的概念,用于组织程序结构,Go 语言的一个文件都要归属于一个包,而不能单独存在。
3) 垃圾回收机制,内存自动回收,不需开发人员管理
4) 天然并发 (重要特点)
(1) 从语言层面支持并发,实现简单
(2) goroutine,轻量级线程,可实现大并发处理,高效利用多核。
(3) 基于 CPS 并发模型(Communicating Sequential Processes )实现
5) 吸收了管道通信机制,形成 Go 语言特有的管道 channel 通过管道 channel , 可以实现不同的 goroute
之间的相互通信。
6) 函数可以返回多个值。举例:
//写一个函数,实现同时返回 和,差
//go 函数支持返回多个值
func getSumAndSub(n1 int, n2 int) (int, int ) {
sum := n1 + n2 //go 语句后面不要带分号.
sub := n1 - n2
return sum , sub
}
7) 新的创新:比如切片 slice、延时执行 defer
2.8 Go 语言快速开发入门
2.8.1需求
要求开发一个 hello.go 程序,可以输出 "hello,world”
2.8.2开发的步骤
1) 开发这个程序/项目时,go 的目录结构怎么处理.
对上图的说明
(1) go 文件的后缀是 .go
(2) package main
表示该 MyFamilyAccount.go 文件所在的包是 utils, 在 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 文件即可
5) 注意:通过 go run 命令可以直接运行 hello.go 程序 [类似执行一个脚本文件的形式]
·Golang 执行流程分析
Ø 如果是对源码编译后,再执行,Go 的执行流程如下图
Ø 如果我们是对源码直接 执行 go run 源码,Go 的执行流程如下图
Ø 两种执行流程的方式区别
如果是对源码编译后,再执行,Go 的执行流程如下图 Ø
如果我们是对源码直接 执行 go run 源码,Go 的执行流程如下图 Ø
Ø 两种执行流程的方式区别
1) 如果我们先编译生成了可执行文件,那么我们可以将该可执行文件拷贝到没有 go 开发环境的机
器上,仍然可以运行
2) 如果我们是直接 go run go 源代码,那么如果要在另外一个机器上这么运行,也需要 go 开发
环境,否则无法执行。
3) 在编译时,编译器会将程序运行依赖的库文件包含在可执行文件中,所以,可执行文件变大了
很多。
·编译和运行说明
1) 有了 go 源文件,通过编译器将其编译成机器可以识别的二进制码文件。
2) 在该源文件目录下,通过 go build 对 hello.go 文件进行编译。可以指定生成的可执行文件名,在
windows 下 必须是 .exe 后缀。
3) 如果程序没有错误,没有任何提示,会在当前目录下会出现一个可执行文件(windows 下是.exe
Linux 下是一个可执行文件),该文件是二进制码文件,也是可以执行的程序。
4) 如果程序有错误,编译时,会在错误的那行报错。有助于程序员调试错误.
5) 运行有两种形式
2.8.8Go 程序开发的注意事项
1) Go 源文件以 "go" 为扩展名。
2) Go 应用程序的执行入口是 main()函数。 这个是和其它编程语言(比如 java/c)
3) Go 语言严格区分大小写。
4) Go 方法由一条条语句构成,每个语句后不需要分号(Go 语言会在每行后自动加分号),这也体现出 Golang 的简洁性。
5) Go 编译器是一行行进行编译的,因此我们一行就写一条语句,不能把多条语句写在同一个,否则报错
6) go 语言定义的变量或者 import 的包如果没有使用到,代码不能编译通过。
7) 大括号都是成对出现的,缺一不可。
·语言的转义字符(escape char)
说明:常用的转义字符有如下:
1) \t : 表示一个制表符,通常使用它可以排版。
2) \n :换行符
3) \\ :一个\
4) \" :一个"
5) \r :一个回车 fmt.Println("天龙八部雪山飞狐\r 张飞");
2.11 注释(comment)
2.11.1 介绍注释
用于注解说明解释程序的文字就是注释,注释提高了代码的阅读性;
注释是一个程序员必须要具有的良好编程习惯。将自己的思想通过注释先整理出来,再用代码去
体现。
2.11.2 在 Golang 中注释有两种形式
1) 行注释
Ø 基本语法
// 注释内容
Ø 举例
2) 块注释(多行注释)
Ø 基本语法
/*
注释内容
*/
2.12 规范的代码风格
4) Go 语言的代码风格.
package main
import "fmt"
func main() {
fmt.Println("hello,world!")
}
上面的写法是正确的.
package main
import "fmt"
func main()
{
fmt.Println("hello,world!")尚硅谷 Go 语言课程
}
上面的写法不是正确,Go 语言不允许这样编写。 【Go 语言不允许这样写,是错误的!】
Go 设计者思想: 一个问题尽量只有一个解决方法
·Golang 官方编程指南
Ø 说明: Golang 官方网站 https://golang.org
Ø 点击上图的 tour -> 选择 简体中文就可以进入中文版的 Go 编程指南。
Ø Golang 官方标准库 API 文档, https://golang.org/pkg
可以查看 Golang 所有包下的函数和使用
2.14 Golang 标准库 API 文档
1) API (Application Programming Interface,应用程序编程接口)是 Golang 提供的基本编程接口。
2) Go 语言提供了大量的标准库,因此 google 公司 也为这些标准库提供了相应的 API 文档,用于告
诉开发者如何使用这些标准库,以及标准库包含的方法。
3) Golang 中文网 在线标准库文档: https://studygolang.com/pkgdoc
4) Golang 的包和源文件和函数的关系简图
5) 有一个离线版的 Golang_Manual_By_AstaXie_20120522.chm
2.15 Dos 的常用指令(了解)
2.15.1 dos 的基本介绍
Dos: Disk Operating System 磁盘操作系统, 简单说一下 windows 的目录结构
2.15.2 dos 的基本操作原理
2.15.3 目录操作指令
Ø 查看当前目录是什么
Ø 切换到其他盘下:盘符号 F 盘
案例演示:
Ø 切换到当前盘的其他目录下 (使用相对路径和绝对路径演示)
Ø
Ø切换到上一级:
案例演示:
Ø 切换到根目录:
案例演示:
Ø 新建目录 md (make directory)
新建一个目录:
新建多个目录:
Ø 删除目录
删除空目录
删除目录以及下面的子目录和文件,不带询问
删除目录以及下面的子目录和文件,带询问
2.15.4 文件的操作
Ø 新建或追加内容到文件
案例演示:
Ø 复制或移动文件
复制
移动
Ø 删除文件
删除指定文件
删除所有文件
2.15.5 其它指令
Ø 清屏
cls [苍老师]
Ø 退出 dos
exit
·本章的知识回顾
Ø Go 语言的 SDK 是什么?
SDK 就是软件开发工具包。我们做 Go 开发,首先需要先安装并配置好 sdk.
Ø Golang 环境变量配置及其作用。
GOROOT: 指定 go sdk 安装目录。
Path: 指令 sdk\bin 目录:go.exe
godoc.exe gofmt.exe
GOPATH: 就是 golang 工作目录:我们的所有项目的源码都这个目录下。
Ø Golang 程序的编写、编译、运行步骤是什么? 能否一步执行?
编写:就是写源码
编译:go build 源码 =》 生成一个二进制的可执行文件
运行:1. 对可执行文件运行 xx.exe ./可执行文件 2. go run 源码
Ø Golang 程序编写的规则。
- go 文件的后缀 .go
2) go 程序区分大小写
3) go 的语句后,不需要带分号
4) go 定义的变量,或者 import 包,必须使用,如果没有使用就会报错
5) go 中,不要把多条语句放在同一行。否则报错
6) go 中的大括号成对出现,而且风格
func main() {
//语句
}
第 3 章 Golang 变量
变量
Golang 变量使用的三种方式
- 第一种:指定变量类型,声明后若不赋值,使用默认值
- 第二种:根据值自行判定变量类型(类型推导)
(3) 第三种:省略 var, 注意 :=左侧的变量不应该是已经声明过的,否则会导致编译错误
package main
import "fmt"
func main() {
var i int = 10 // var 变量名 类型 = 值 int的默认值为0
var a int // int类型的默认值为0,因此a==0;
var j = 1.2 // var 变量名 = 值
name := "szc" // 变量名 := 值,自动推导类型
fmt.Println("i = ", i, ", j = " , j , ", name = ", name)}
(4) 多变量声明
在编程中,有时我们需要一次性声明多个变量,Golang 也提供这样的语法
举例说明:
var a, sex, b = 1, "male", 7
a, sex, b := 2, "male", 4
(5)如何一次性声明多个全局变量【在 go 中函数外部定义变量就是全局变量】:
一次声明多个变量,变量名和值一一对应
函数外声明全局变量(两种方式:)
var (
n1 = 1
n2 = 2
n3 = 3)
var n4 = "n4"
func main() {
fmt.Println("n1 = ", n1, ", n2 = ", n2, "n3 = ", n3, ", n4 = ", n4)}
变量声明后必须使用,而且不能隐式改变类型(int转float)
Golang 的变量如果没有赋初值,编译器会使用默认值, 比如 int 默认值 0, string 默认值为空串, 小数默认为 0
常量
常量必须赋初值,而且不可更改
const tax int = 1
const name_ = "szc"
const b = 4 / 2
// const b_ = getVal() // 编译期值不确定// num := 1// const b_ = num / 2 // 编译期值不确定// const tax_0 int // 必须赋初值// tax = 2 // 不可修改
常量只能修饰布尔、数值、字符串类型
也可以这么声明常量,可以在函数里面声明
const (
a = iota //0
b = iota //1
c = iota //2
d,e = iota,iota //3 3)
fmt.Println(a, b, c, d, e) // 0 1 2 3 3 依次加1
上面b和c可以不写= iota,但是a必须写
3.6 程序中 +号的使用
1) 当左右两边都是数值型时,则做加法运算
2) 当左右两边都是字符串,则做字符串拼接
第 4 章数据类型
·值类型,引用类型
·基本的数据类型 int、float、bool、string、数组、结构体struct
·引用类型包括指针,slice切片,map ,chan ,interface
·值类型和引用类型的使用特点
值类型 直接存放值,内存通常在栈中分配;
引用类型变量存储的地址(也就是通过指针访问类型里面的数据),通常真正的值在堆上分配。当没 有变量引用这个地址的时候,该值会被gc回收。
·整数的各个类型
- Golang 各整数类型分:有符号和无符号,int uint 的大小和系统有关。
int 的有符号的类型:
int 的无符号的类型:
数值超过会报错。
- 如何在程序查看某个变量的字节大小和数据类型 (使用较多)
%d与T%
Golang 的整型默认声明为 int 型
小数类型/浮点型
小数类型就是用于存放小数的,比如 1.2 0.23 -1.911
对上图的说明:
1) 关于浮点数在机器中存放形式的简单说明,浮点数=符号位+指数位+尾数位
2) 尾数部分可能丢失,造成精度损失。 -123.0000901
说明:float64 的精度比 float32 的要准确.
说明:如果我们要保存一个精度高的数,则应该选用 float64
- 浮点型的存储分为三部分:符号位+指数位+尾数位 在存储过程中,精度会有丢失
·浮点型使用细节
1) Golang 浮点类型有固定的范围和字段长度,不受具体 OS(操作系统)的影响。
2) Golang 的浮点型默认声明为 float64 类型。
3) 浮点型常量有两种表示形式
·十进制数形式:
(可以没有0,但必须有小数点)
·科学计数法形式:如:
相当于5.1234e2 = 5.12 * 10 的 2 次方。
5.12E-2 = 5.12/10 的 2 次方
字符类型
3.10.1 基本介绍
Golang 中没有专门的字符类型,如果要存储单个字符(字母),一般使用 byte 来保存.
字符串就是一串固定长度的字符连接起来的字符序列。传统的字符串是由字符组成的,而 Go 的字符串不同,它是由字节组成的。
3.10.2 案例演示
对上面代码说明
1) 如果我们保存的字符在 ASCII 表的,比如[0-1, a-z,A-Z..]直接可以保存到 byte (因为2127范围大于byte)
2) 如果我们保存的字符对应码值大于 255,这时我们可以考虑使用 int 类型保存
3) 如果我们需要按照字符的方式输出(%c),这时我们需要格式化输出,即 fmt.Printf(“%c”, c1)
字符类型使用细节
- 字符常量是用单引号('')括起来的单个字符。
例如:var c1 byte = 'a'
var c2 int = '中'
var c3 byte = '9'
- Go 中允许使用转义字符 '\’来将其后的字符转变为特殊字符型常量。
例如:var c3 char = ‘\n’ ,'\n'表示换行符
3) Go语言的字符使用UTF-8编码,如果想查询字符对应的utf8码值
http://www.mytju.com/classcode/tools/encode_utf8.asp
英文字母1个字节;汉字3 个字节
4) 在 Go 中,字符的本质是一个整数,直接输出时,是该字符对应的 UTF-8 编码的码值。
5) 可以直接给某个变量赋一个数字,然后按格式化输出时%c,会输出该数字对应的 unicode 字符
6) 字符类型是可以进行运算的,相当于一个整数,因为它都对应有 Unicode 码.
字符类型本质探讨
1) 字符型 存储到 计算机中,需要将字符对应的码值(整数)找出来
存储:字符--->对应码值---->二进制-->存储
读取:二进制----> 码值 ----> 字符 --> 读取
2) 字符和码值的对应关系是通过字符编码表决定的(是规定好)
- Go 语言的编码都统一成了 utf-8。非常的方便,很统一,再也没有编码乱码的困扰了
布尔类型
基本介绍
1) 布尔类型也叫 bool 类型,bool 类型数据只允许取值 true 和 false
2) bool 类型占 1 个字节。
3) bool 类型适于逻辑运算,一般用于程序流程控制[注:这个后面会详细介绍]:
Ø if 条件控制语句;
Ø for 循环控制语句
案例演示
string 类型
基本介绍
字符串就是一串固定长度的字符连接起来的字符序列。Go 的字符串是由单个字节连接起来的。Go
语言的字符串的字节使用 UTF-8 编码标识 Unicode 文本
3.12.2 案例演示
3.12.3 string 使用注意事项和细节
1) Go 语言的字符串的字节使用 UTF-8 编码标识 Unicode 文本,这样 Golang 统一使用 UTF-8 编码,中文
乱码问题不会再困扰程序员。
2) 字符串一旦赋值了,字符串就不能修改了:在 Go 中字符串是不可变的。
3) 字符串的两种表示形式
(1) 双引号, 会识别转义字符
(2) 反引号,以字符串的原生形式输出,包括换行和特殊字符,可以实现防止攻击、输出源代码等效果
4) 字符串拼接方式
5) 当一行字符串太长时,需要使用到多行字符串,可以如下处理
基本数据类型的默认值
3.13.1 基本介绍
在 go 中,数据类型都有一个默认值,当程序员没有赋值时,就会保留默认值,在 go 中,默认值
又叫零值。
3.13.2 基本数据类型的默认值如下
3.14 基本数据类型的相互转换
3.14.1 基本介绍
Golang 和 java / c 不同,Go 在不同类型的变量之间赋值时需要显式转换。也就是说 Golang 中数
据类型不能自动转换。
3.14.2 基本语法
表达式 T(v) 将值 v 转换为类型 T
T: 就是数据类型,比如 int32,int64,float32 等等
v: 就是需要转换的变量
%v表示值,与%d相当。
基本数据类型相互转换的注意事项
1) Go 中,数据类型的转换可以是从 表示范围小-->表示范围大,也可以 范围大--->范围小
2) 被转换的是变量存储的数据(即值),变量本身的数据类型并没有变化!
3) 在转换中,比如将 int64 转成 int8 【-128---127】 ,编译时不会报错,只是转换的结果是按
溢出处理,和我们希望的结果不一样。 因此在转换时,需要考虑范围.
·例子:
正确方式:
基本数据类型和 string 的转换
基本介绍
在程序开发中,我们经常将基本数据类型转成 string,或者将 string 转成基本数据类型。
基本类型转 string 类型
Ø 方式 1:fmt.Sprintf("%参数", 表达式) 【个人习惯这个,灵活】
函数的介绍:
参数需要和表达式的数据类型相匹配
fmt.Sprintf().. 会返回转换后的字符串
Ø 案例演示
Ø 方式 2:使用 strconv 包的函数
string 类型转基本数据类型
Ø 使用时 strconv 包的函数
Ø 案例演示
string 转基本数据类型的注意事项
在将 String 类型转成 基本数据类型时,要确保 String 类型能够转成有效的数据,
比如 我们可以把 "123" , 转成一个整数,但是不能把 "hello" 转成一个整数,如果这样做,Golang 直接将其转成 0,其它类型也是一样的道理. float => 0 bool => false
案例说明:
指针
基本介绍
1) 基本数据类型,变量存的就是值,也叫值类型
2) 获取变量的地址,用&,比如: var num int, 获取 num 的地址:&num
分析一下基本数据类型在内存的布局.
3) 指针类型,指针变量存的是一个地址,这个地址指向的空间存的才是值
比如:var ptr *int = &num
4) 获取指针类型所指向的值,使用:*,比如:var ptr *int, 使用*ptr 获取 ptr 指向的值
5) 一个案例再说明
3.16.2 案例演示
1) 写一个程序,获取一个 int 变量 num 的地址,并显示到终端
2) 将 num 的地址赋给指针 ptr , 并通过 ptr 去修改 num 的值.
//演示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) //发现 ptr ==&i
fmt.Printf("ptr 的地址=%v", &ptr) //发现 &ptr 就是0xc04206c20,即ptr本身地址
fmt.Printf("ptr 指向的值=%v", *ptr)//发现 *ptr ==10,即i的值,此时如果修改*ptr,则i也跟着变化
}
指针的使用细节
1) 值类型,都有对应的指针类型, 形式为 *数据类型,比如 int 的对应的指针就是 *int, float32
对应的指针类型就是 *float32, 依次类推。
- 值类型包括:基本数据类型 int 系列, float 系列, bool, string 、数组和结构体 struct
值类型和引用类型
值类型和引用类型的说明
- 值类型:基本数据类型 int 、 float、 bool、 string 、数组、结构体struct
- 引用类型:指针、slice 切片、map、管道 chan、interface 等都是引用类型
值类型和引用类型的使用特点
1) 值类型:变量直接存储值,内存通常在栈中分配
示意图:
2) 引用类型:变量存储的是一个地址,这个地址对应的空间才真正存储数据(值),内存通常在堆
上分配,当没有任何变量引用这个地址时,该地址对应的数据空间就成为一个垃圾,由 GC 来回收
示意图:
3) 内存的栈区和堆区示意图
标识符的命名规范
标识符概念
1) Golang 对各种变量、方法、函数等命名时使用的字符序列称为标识符
2) 凡是自己可以起名字的地方都叫标识符
标识符的命名规则
1) 由 26 个英文字母大小写,0-9 ,_ 组成
2) 数字不可以开头。var num int //ok var 3num int //error
3) Golang 中严格区分大小写。
var num int
var Num int
说明:在 golang 中,num 和 Num 是两个不同的变量
- 标识符不能包含空格。
5) 下划线"_"本身在 Go 中是一个特殊的标识符,称为空标识符。可以代表任何其它的标识符,但
是它对应的值会被忽略(比如:忽略某个返回值)。所以仅能被作为占位符使用,不能作为标识符使用
6)不能以系统保留关键字作为标识符(一共有 25 个),比如 break,if 等等...
除了以上介绍的这些关键字,Go 语言还有 36 个预定义标识符,其中包含了基本类型的名称和一些基本的内置函数,见下表:
标识符的案例
hello // ok
hello12 //ok
1hello // error ,不能以数字开头
h-b // error ,不能使用 -
x h // error, 不能含有空格
h_4 // ok
_ab // ok
int // ok , 我们要求大家不要这样使用
float32 // ok , 我们要求大家不要这样使用
_ // error
Abc // ok
标识符命名注意事项
1) 包名:保持 package 的名字和目录保持一致,尽量采取有意义的包名,简短,有意义,不要和
标准库不要冲突 fmt
2) 变量名、函数名、常量名:采用驼峰法
举例:
var stuName string = “tom”
var goodPrice float32 = 1234.5
形式: xxxYyyyyZzzz ...
3) 如果变量名、函数名、常量名首字母大写,则可以被其他的包访问;如果首字母小写,则只能
在本包中使用 ( 注:可以简单的理解成,首字母大写是公开的,首字母小写是私有的) ,在 golang 没有
public , private 等关键字。
案例演示:
第 4 章 运算符
·运算符的基本介绍
运算符是一种特殊的符号,用以表示数据的运算、赋值和比较等
运算符是一种特殊的符号,用以表示数据的运算、赋值和比较等
1) 算术运算符
2) 赋值运算符
3) 比较运算符/关系运算符
4) 逻辑运算符
5) 位运算符
6) 其它运算符
·算术运算符
算术运算符是对数值类型的变量进行运算的,比如:加减乘除。在 Go 程序中使用的非常多
·算术运算符的一览表
·案例演示
Ø 案例演示算术运算符的使用。
+, - , * , / , %, ++, -- , 重点讲解 /、%
自增:++
自减:--
Ø 演示 / 的使用的特点(向下取整)
Ø 演示 % 的使用特点
// 演示 % 的使用
// 看一个公式 a % b = a - a / b * b
fmt.Println("10%3=", 10 % 3) // =1
fmt.Println("-10%3=", -10 % 3) // = -10 - (-10) / 3 * 3 = -10 - (-9) = -1
fmt.Println("10%-3=", 10 % -3) // =1
fmt.Println("-10%-3=", -10 % -3) // =-1
Ø ++ 和 --的使用
·算术运算符使用的注意事项
- 对于除号 "/",它的整数除和小数除是有区别的:整数之间做除法时,只保留整数部分而舍弃小数部分。
例如: x := 19/5 ,结果是 3
- 当对一个数取模时,可以等价 a%b=a-a/b*b , 这样我们可以看到 取模的一个本质运算。
- Golang 的自增自减只能当做一个独立语言使用时,不能这样使用
- Golang 的++ 和 -- 只能写在变量的后面,不能写在变量的前面,
即:只有 a++ a-- 没有 ++a --a
5) Golang 的设计者去掉 c / java 中的 自增自减的容易混淆的写法,让Golang 更加简洁,统一。
(强制性的)
func main() {
//在golang中,++ 和 -- 只能独立使用.
var i int = 8
var a int
a = i++ //错误,i++只能独立使用
a = i-- //错误, i--只能独立使用
if i++ > 0 {//错误,i++只能独立使用
fmt.Println("ok")
}
var i int = 1
i++
++i // 错误,在golang没有 前++
i--
--i // 错误,在golang没有 前--
fmt.Println("i=", i)
}
·关系运算符(比较运算符)
·案例演示
·逻辑运算符
·基本介绍
用于连接多个条件(一般来讲就是关系表达式),最终的结果也是一个 bool 值
运算符 | 描述 | 实例 |
&& | 逻辑 AND 运算符。 如果两边的操作数都是 True,则条件 True,否则为 False。 | (A && B) 为 False |
|| | 逻辑 OR 运算符。 如果两边的操作数有一个 True,则条件 True,否则为 False。 | (A || B) 为 True |
! | 逻辑 NOT 运算符。 如果条件为 True,则逻辑 NOT 条件 False,否则为 True。 | !(A && B) 为 True |
·注意事项和细节说明
1) &&也叫短路与:如果第一个条件为 false,则第二个条件不会判断,最终结果为 false
2) ||也叫短路或:如果第一个条件为 true,则第二个条件不会判断,最终结果为 true
3) 案例演示
//声明一个函数(测试)
func test() bool {
fmt.Println("test....")
return true
}
func main() {
var i int = 10
//短路与
//说明 因为 i < 9 为 false ,因此后面的 test() 就不执行
// if i < 9 && test() {
// fmt.Println("ok...")
// }
if i > 9 || test() {
fmt.Println("hello...")
}
}
·赋值运算符
运算符 | 描述 | 实例 |
& | 按位与运算符”&”是双目运算符。 其功能是参与运算的两数各对应的二进位相与。 | (A & B) 结果为 12, 二进制为 0000 1100 |
| | 按位或运算符”|”是双目运算符。 其功能是参与运算的两数各对应的二进位相或 | (A | B) 结果为 61, 二进制为 0011 1101 |
^ | 按位异或运算符”^”是双目运算符。 其功能是参与运算的两数各对应的二进位相异或,当两对应的二进位相异时,结果为1。 | (A ^ B) 结果为 49, 二进制为 0011 0001 |
<< | 左移运算符”<<”是双目运算符。左移n位就是乘以2的n次方。 其功能把”<<”左边的运算数的各二进位全部左移若干位,由”<<”右边的数指定移动的位数,高位丢弃,低位补0。 | A << 2 结果为 240 ,二进制为 1111 0000 |
>> | 右移运算符”>>”是双目运算符。右移n位就是除以2的n次方。 其功能是把”>>”左边的运算数的各二进位全部右移若干位,”>>”右边的数指定移动的位数。 | A >> 2 结果为 15 ,二进制为 0000 1111 |
·下表列出了所有Go语言的赋值运算符。假定 A 为21
运算符 | 描述 | 实例 |
= | 简单的赋值运算符,将一个表达式的值赋给一个左值 | C = A 将 A 赋值给 C,结果:21 |
+= | 相加后再赋值 | C += A 等于 C = C + A,结果:42 |
-= | 相减后再赋值 | C -= A 等于 C = C - A,结果:21 |
*= | 相乘后再赋值 | C *= A 等于 C = C * A,结果:441 |
/= | 相除后再赋值 | C /= A 等于 C = C / A,结果:21 |
%= | 求余后再赋值 | C %= A 等于 C = C % A,结果:0//不记入计算 |
<<= | 左移后赋值 | C <<= 2 等于 C = C << 2,结果:84 |
>>= | 右移后赋值 | C >>= 2 等于 C = C >> 2,结果:21 |
&= | 按位与后赋值 | C &= 2 等于 C = C & 2,结果:0 |
^= | 按位异或后赋值 | C ^= 2 等于 C = C ^ 2,结果:2 |
|= | 按位或后赋值 | C |= 2 等于 C = C | 2,结果:2 |
·其他运算符
运算符 | 描述 | 实例 |
& | 返回变量存储地址 | &a; 将给出变量的实际地址。 |
* | 指针变量。 | *a; 是一个指针变量 |
·赋值运算符的特点
1) 运算顺序从右往左
2) 赋值运算符的左边 只能是变量,右边 可以是变量、表达式、常量值
3) 复合赋值运算符等价于下面的效果
比如:a += 3 等价于 a = a + 3
- 不支持三元运算符合,可用if -else来实现。
·键盘输入语句
·介绍
在编程中,需要接收用户输入的数据,就可以使用键盘输入语句来获取。InputDemo.go
·步骤 :
1) 导入 fmt 包
2) 调用 fmt 包的 fmt.Scanln() 或者 fmt.Scanf()
·案例演示:
要求:可以从控制台接收用户信息,【姓名,年龄,薪水, 是否通过考试 】。
- 使用 fmt.Scanln() 获取
//要求:可以从控制台接收用户信息,【姓名,年龄,薪水, 是否通过考试 】。
//方式1 fmt.Scanln
//1先声明需要的变量
var name string
var age byte
var sal float32
var isPass bool
fmt.Println("请输入姓名 ")
//当程序执行到 fmt.Scanln(&name),程序会停止在这里,等待用户输入,并回车
fmt.Scanln(&name)
fmt.Println("请输入年龄 ")
fmt.Scanln(&age)
fmt.Println("请输入薪水 ")
fmt.Scanln(&sal)
fmt.Println("请输入是否通过考试 ")
fmt.Scanln(&isPass)
fmt.Printf("名字是 %v \n 年龄是 %v \n 薪水是 %v \n 是否通过考试 %v \n", name, age, sal, isPass)
- 使用 fmt.Scanf() 获取
var name string
var age byte
var sal float32
var isPass bool
//方式2:fmt.Scanf,可以按指定的格式输入
fmt.Scanf("%s %d %f %t", &name, &age, &sal, &isPass)
fmt.Printf("名字是 %v \n年龄是 %v \n 薪水是 %v \n 是否通过考试 %v \n", name, age, sal, isPass)
传入&,即可改变变量的值。
·进制
对于整数,有四种表示方式:
1) 二进制:0,1 ,满 2 进 1。
在 golang 中,不能直接使用二进制来表示一个整数,它沿用了 c 的特点。
2) 十进制:0-9 ,满 10 进 1。
3) 八进制:0-7 ,满 8 进 1. 以数字 0 开头表示。
4) 十六进制:0-9 及 A-F,满 16 进 1. 以 0x 或 0X 开头表示。
此处的 A-F 不区分大小写。
·进制的图示
·位运算
4.12.1 位运算的思考题
1) 请看下面的代码段,回答 a,b,c,d 结果是多少?
func main() {
var a int = 1 >> 2
var b int = -1 >> 2
var c int = 1 << 2
var d int = -1 << 2
//a,b,c,d 结果是多少
fmt.Println("a=", a)
fmt.Println("b=", b)
fmt.Println("c=", c)
fmt.Println("d=", d)
}
2) 请回答在 Golang 中,下面的表达式运算的结果是:
func main() {
fmt.Println(2&3)
fmt.Println(2|3)
fmt.Println(13&7)
fmt.Println(5|4) //?
fmt.Println(-3^3) //?
}
·二进制在运算中的说明
二进制是逢 2 进位的进位制,0、1 是基本算符。
现代的电子计算机技术全部采用的是二进制,因为它只使用 0、1 两个数字符号,非常简单方便,易于用电子方式实现。计算机内部处理的信息,都是采用二进制数来表示的。二进制(Binary)数用 0 和 1 两个数字及其组合来表示任何数。进位规则是“逢 2 进 1”,数字 1 在不同的位上代表不同的值, 按从右至左的次序,这个值以二倍递增。在计算机的内部,运行各种运算时,都是以二进制的方式来运行。
·位运算符和移位运算符
Ø Golang 中有 3 个位运算
分别是”按位与&、按位或|、按位异或^,它们的运算规则是:
按位与& :
两位全为1,结果为 1,否则为 0
按位或| :
两位有一个为 1,结果为 1,否则为 0
按位异或 ^ :
两位一个为 0,一个为 1,结果为 1,否则为 0
Ø Golang 中有 2 个移位运算符:
>>、<< 右移和左移,运算规则:
右移运算符 >>:低位溢出,符号位不变,并用符号位补溢出的高位
左移运算符 <<: 符号位不变,低位补 0
Ø 案例演示
a := 1 >> 2 // 0000 0001 =>0000 0000 = 0
c := 1 << 2 // 0000 0001 ==> 0000 0100 => 4
第 5 章 程序流程控制
5.1 程序流程控制介绍
·if-else 流程控制
基本语法:
if 表达式1 { // 表达式可以写(),官方不推荐写
//代码块
} else if 表达式2{ // else if 可省略,不能换行写
//代码块
} else { // else 可省略,不能换行写
//代码块
}
switch分支结构
基本语法
switch 表达式 {
case 表达式1,表达式2,…… :
// 语句块1
case 表达式3,表达式4,…… :
// 语句块2
// 多个case,结构同上
default :
// 语句块3
}
switch 的执行的流程:
- 先执行表达式,得到值,然后和 case 的表达式进行比较,如果相等,就匹配到,然后执行对应的 case 的语句块,然后退出 switch 控制。
- 如果 switch的表达式的值没有和任何的 case 的表达式匹配成功,则执行 default的语句块。
- 多个表达式使用逗号间隔
for循环
传统for
基本语法
for 循环变量初始化 ;循环条件 ;循环变量迭代 {
//循环操作
}
例:
for i := 0 ; i < 10 ; i++ {
//代码块}
注:Go中没有while,do…while循环,Go语言支持goto跳转,但不推荐使用
for-range
for--range 的基本语法:只有两个关键字:for 、range 构成。
for indexs, value:= range str{
}
这是一种同时获取索引和值或键值的遍历方式
str := "拜仁慕尼黑来自德甲"
for index, s := range str {
fmt.Printf("%d --- %c ",index, s)
}
输出:0 — 拜 3 — 仁 6 — 慕 9 — 尼 12 — 黑 15 — 来 18 — 自 21 — 德 24 — 甲
·break
break用于终止某个语句块的执行,用于中断当前for或跳出switch语句
break 出现在多层嵌套循环中可以使用标签(label)表明要终止哪个循环
for i := 0 ; i < 4 ; i++ {
for j := 0 ; j < 10 ; j++ {
if j==2 {
break // break 默认会跳出最近的for循环
}
fmt.Println("j=",j)
}}
输出结果:
j= 0
j= 1
j= 0
j= 1
j= 0
j= 1
j= 0
j= 1
·使用标签
label1:
for i := 0 ; i < 4 ; i++ {
for j := 0 ; j < 10 ; j++ {
if j==2 {
break label1 // 一旦触发直接终止i的循环
}
fmt.Println("j=",j)
}
fmt.Println("i=",i)
}
输出结果:
j= 0
j= 1
·continue
continue用于结束本次循环,在多层嵌套时可用标签跳转,用法同上(break是终止循环,continue是跳过本次循环)
·跳转控制语句-goto
1) Go 语言的 goto 语句可以无条件地转移到程序中指定的行。
2) goto 语句通常与条件语句配合使用。可用来实现条件转移,跳出循环体等功能。
3) 在 Go 程序设计中一般不主张使用 goto 语句,以免造成程序流程的混乱,使理解和调试程序都产生 困难
· goto 基本语法
goto label
.. .
label: statement
·快速入门案例
var n int = 30
//演示goto的使用
fmt.Println("ok1")
if n > 20 {
goto label1//label1自定义名字
}
fmt.Println("ok2")
fmt.Println("ok3")
fmt.Println("ok4")
label1:
fmt.Println("ok5")
fmt.Println("ok6")
fmt.Println("ok7")
·跳转控制语句-return
return 使用在方法或者函数中,表示跳出所在的方法或函数,在讲解函数的时候,会详细的介绍。
说明
1) 如果 return 是在普通的函数,则表示跳出该函数,即不再执行函数中 return 后面代码,也可以
理解成终止函数。
2) 如果 return 是在 main 函数,表示终止 main 函数,也就是说终止程序。