Cris 的 Go 笔记(上)
Author:Cris
1. Go 的介绍和安装
1.1 Go 语言的特点
Go 语言保证了既能到达静态编译语言的安全和性能,又达到了动态语言开发维护的高效率 ,使用一个表达式来形容 Go 语言:Go = C + Python , 说明 Go 语言既有 C 静态语言程 序的运行速度,又能达到 Python 动态语言的快速开发。
开发人员在为项目选择语言时,不得不在快速开发和性能之间做出选择。C和C++这类语言提供了很快的执行速度,而 Ruby 和 Python 这类语言则擅长快速开发。Go语言在这两者间架起了桥梁,不仅提供了高性能的语言,同时也让开发更快速。
1.2 Go 的优势
-
学习曲线平滑
Go 语言本身包含类C语法、GC机制和常用工具,几乎支持大多数你在其他语言见过的特性:继承、重载、对象等.相比较其他语言(Java,c++), Go入门更加容易
-
效率高
Go拥有接近C的运行效率和接近PHP的开发效率,很符合当下软件开发迭代速度块,高性能,高效率的特点
静态类型语言,可以在编译的时候检查出来隐藏的大多数问题,又有动态语言的开发效率,有很多的包可以使用,写起来的效率很高
-
出身名门
Google公司聚集了一批牛人,在各种编程语言称雄争霸的局面下推出新的编程语言,自然有它的战略考虑。而且从Go语言的发展态势来看,Google对它这个新的宠儿还是很看重的,Go自然有一个良好的发展前途.
-
天然支持并发
语言层面支持并发,这个就是Go最大的特色,天生的支持并发。可以充分的利用多核,很容易的实现并发
-
强大的标准库
包括互联网应用、系统编程和网络编程。Go里面的标准库基本上已经是非常稳定了,特别是我这里提到的三个,网络层、系统层的库非常实用.并且Go提供了软件生命周期(开发、测试、部署、维护等等)的各个环节的工具,如go tool、gofmt、go test,最大限度确保 Go 程序的稳定性
1.3 Go适合做什么
常见的 Go 开发职位
- 区块链开发
- web 端服务器开发
- 分布式/云计算系统开发
1.4 Go 的安装
这里参考 Go 的官网
docs.studygolang.com/doc/install
Cris 使用的是 Windows 平台,直接下载 msi 安装包即可
然后一路安装 next 即可
安装完毕后,打开 cmd,然后验证 Go 的安装
打开环境变量
打开 cmd 窗口
表示 Go 的开发环境ok
然后设置Go 的开发空间(推荐)
GOPATH 设置如下(表示Go 开发项目的放置路径)
1.5 Go 的开发 IDE
这里个人选择 Visual Studio Code,毕竟之前开发的Python和Shell都使用的这个,感觉相当好用
当然还可以选择 GoLand 等专门开发 Go 的 IDE
1.6 Go 的学习路线图
github.com/gocn/knowle…
1.7 Go 的 hello world 以及 Visual Studio Code 配置
打开 Visual Studio Code,开发一个最简单的 Go 程序
为了方便开发,我们需要为 Visual Studio Code 安装一些插件,具体步骤如下
然后将这些插件放到 Go 安装路径 /bin 目录下,接着重启 Visual Studio Code
开发一个Go 的 hello world 程序 test.go
// Go文件所在包
package main
// 导入 fmt 包,用于格式化输入,输出
import "fmt"
// 主函数
func main() {
// 调用函数
fmt.Println("cris")
}
复制代码
然后执行 go build 命令
还可以通过 go run 命令直接运行 go 文件(生产环境都是先编译,后执行)
Go 项目开发路径整理
1.8 Go 程序执行流程分析
注意
- 如果我们先编译生成了可执行文件,那么我们可以将该可执行文件拷贝到没有 go 开发环境的机 器上,仍然可以运行
- 如果我们先编译生成了可执行文件,那么我们可以将该可执行文件拷贝到没有 go 开发环境的机 器上,仍然可以运行
- 在编译时,编译器会将程序运行依赖的库文件包含在可执行文件中,所以,可执行文件变大了 很多
关于 Go 的编译和执行
- 有了 go 源文件,通过编译器将其编译成机器可以识别的二进制码文件
- 在该源文件目录下,通过 go build 对 test.go 文件进行编译。可以指定生成的可执行文件名,在 windows 下 必须是 .exe 后缀
- 如果程序没有错误,没有任何提示,会在当前目录下会出现一个可执行文件(windows 下是.exe Linux 下是一个可执行文件),该文件是二进制码文件,也是可以执行的程序
- 如果程序有错误,编译时,会在错误的那行报错。有助于程序员调试错误
- 运行有两种形式
- go build .go->执行可执行文件(windows是 .exe)
- go run .go
2 Go 基础开发
2.1 Go 开发注意点
- Go 源文件以 "go" 为扩展名
- Go 应用程序的执行入口是 main()函数。 这个是和其它编程语言(比如 java/c)
- Go 语言严格区分大小写
- Go 方法由一条条语句构成,每个语句后不需要分号(Go 语言会在每行后自动加分号),这也体现了 Go的简洁性
- Go 编译器是一行行进行编译的,因此我们一行就写一条语句,不能把多条语句写在同一个,否 则报错
- go 语言定义的变量或者 import 的包如果没有使用到,代码不能编译通过
- 小括号/大括号成对出现
2.2 Go 语言的转义字符(escape char)
常用的转义字符
-
\t: 表示一个制表符,可以用于排版
-
\n: 换行符
-
\\ : \
-
\r: 回车, \r 后面的内容会依次替换前面的内容
package main import "fmt" func main() { fmt.Println("cris") fmt.Print("james\n") fmt.Println("cirs\rhahah") // \r 表示回车但不换行 } 复制代码
2.3 注释和格式化
// 行注释
/*
多行注释
*/
复制代码
这里建议使用快捷键
设置每行代码长度
2.4 官网文档
Golang 官方网站 golang.org
Golang 官方标准库 API 文档, golang.org/pkg(studygolang.com/pkgdoc) 可以查看 Golang 所有包下的函数和使用
Golang 中文网站 studygolang.com/
2.5 DOS 操作简述
Dos: Disk Operating System 磁盘操作系统.通常在 windows 上程序员偶尔会通过命令的方式来操作系统,例如最常见的 CMD 窗口
dos 操作简单流程
常用 dos 命令
cd : 切换目录
cd .. : 切换到上一级目录
cd \ : 切换到根目录
dir : 查看当前目录
md 文件夹 : 新建一个文件夹
del 文件 : 删除文件
rd 空目录 : 删除空目录
rd /q/s 目录名 : 直接删除该目录及以下所有文件和目录
cp/move 文件 : 复制/移动文件
cls : 清屏
exit : 退出终端
创建空文件
追加/创建有内容的文件
3. Go 中的变量
3.1 变量使用步骤:
- 声明变量
- 赋值
- 使用
3.2 变量注意事项
-
变量表示内存中的一个存储区域
-
该区域有自己的名称(变量名)和类型(数据类型)
-
Golang 变量使用的三种方式
-
第一种:指定变量类型,声明后若不赋值,使用默认值
package main import "fmt" func main() { var a int fmt.Print("a=", a) } 复制代码
-
根据值自行判定变量类型(类型推导)
package main import "fmt" func main() { var a = 12 fmt.Print("a=", a) } 复制代码
-
省略 var, 注意 :=左侧的变量不应该是已经声明过的,否则会导致编译错误
package main import "fmt" func main() { a := 12 fmt.Print("a=", a) } 复制代码
-
-
多变量声明
在编程中,有时我们需要一次性声明多个变量,Golang 也提供这样的语法
-
通过手动赋值的方式
func main() { var name, age = "cris", 12 fmt.Print("name=", name, ",age=", age) } 复制代码
-
通过默认值的方式(多个变量数据类型需要一致)
func main() { var name, address string fmt.Print("name=", name, ",address=", address) } 复制代码
-
省略 var 关键字
func main() { name, address := "cris", "重庆" fmt.Print("name=", name, ",address=", address) } 复制代码
-
一次性声明多个全局变量【在 go 中函数外部定义变量就是全局变量】
// 定义多个全局变量方式一 var country, city = "中国", "重庆" // 定义多个全局变量方式二 var ( n1 = 100 n2 = 200 ) 复制代码
-
-
该区域的数据值可以在同一类型范围内不断变化(重点)
-
变量在同一个作用域(在一个函数或者在代码块)内不能重名
-
变量=变量名+值+数据类型,这一点请大家注意,变量的三要素
-
Golang 的变量如果没有赋初值,编译器会使用默认值, 比如 int 默认值 0 string 默认值为空串, 小数默认为 0
3.3 Go 中 + 使用
和 Java 类似,+ 左右两边都是数字,则相加;如果有两个字符串,则拼接
name, address := "james", "江北区"
name = name + "-harden" // james-harden
复制代码
3.4 数据类型
基本数据类型
复杂数据类型
一. 整数
整数类型(有符号)
整数类型(无符号)
var n uint8 = 256 // constant 256 overflows uint8
fmt.Print(n)
复制代码
其他整数类型
整数细节
-
Golang 各整数类型分:有符号和无符号,int uint 的大小和系统有关
-
Golang 的整型默认声明为 int 型
var i = 123 // i 的数据类型是 int fmt.Printf("i 的数据类型是 %T", i) 复制代码
-
如何在程序查看某个变量的字节大小和数据类型
var i = 2 // i 的数据类型是 int,字节大小是 8 fmt.Printf("i 的数据类型是 %T,字节大小是 %d", i, unsafe.Sizeof(i)) 复制代码
-
Golang 程序中整型变量在使用时,遵守保小不保大的原则,即:在保证程序正确运行下,尽量 使用占用空间小的数据类型。【如:年龄】
-
bit: 计算机中的最小存储单位。byte:计算机中基本存储单元。[二进制再详细说] 1byte = 8 bit
二. 浮点型
小数类型就是用于存放小数的,比如 1.2 0.23 -1.911
说明
-
关于浮点数在机器中存放形式的简单说明,浮点数=符号位+指数位+尾数位 说明:浮点数都是有符号的.
-
尾数部分可能丢失,造成精度损失。 -123.0000901
var i float32 = -12.912345678 fmt.Print(i) // -12.912346 复制代码
说明:float64 的精度比 float32 的要准确. 说明:如果我们要保存一个精度高的数,则应该选用 float64
-
浮点型的存储分为三部分:符号位+指数位+尾数位 在存储过程中,精度会有丢失
使用细节
-
Golang 浮点类型有固定的范围和字段长度,不受具体 OS(操作系统)的影响
-
Golang 的浮点型默认声明为 float64 类型
-
浮点型常量有两种表示形式
十进制数形式:如:5.12 .512 (必须有小数点) 科学计数法形式:如:5.1234e2 = 5.12 * 10 的 2 次方; 5.12E-2 = 5.12/10 的 2 次方
-
通常情况下,应该使用 float64 ,因为它比 float32 更精确。[开发中,推荐使用 float64]
三. 字符类型
Golang 中没有专门的字符类型,如果要存储单个字符(字母),一般使用 byte 来保存。 字符串就是一串固定长度的字符连接起来的字符序列。Go 的字符串是由单个字节连接起来的。也 就是说对于传统的字符串是由字符组成的,而 Go 的字符串不同,它是由字节组成的
var a byte = '?'
fmt.Print(a) // 97
fmt.Printf("a=%c", a) // ? 如果需要输出对应的字符,需要格式化
复制代码
ps :
- 如果我们保存的字符在 ASCII 表的,比如[0-1, a-z,A-Z..]直接可以保存到 byte
- 如果我们保存的字符对应码值大于 255,这时我们可以考虑使用 int 类型保存
- 如果我们需要安装字符的方式输出,这时我们需要格式化输出,即 fmt.Printf(“%c”, c1)..
字符使用细节
-
字符常量是用单引号('')括起来的单个字符。例如:var c1 byte = 'a' var c2 int = '中' var c3 byte = '9'
-
Go 中允许使用转义字符 '\’来将其后的字符转变为特殊字符型常量。例如:var c3 char = ‘\n’ ('\n'表示换行符)
-
Go 语 言 的 字 符 使 用 UTF-8 编 码 , 如 果 想 查 询 字 符 对 应 的 utf8 码 值 www.mytju.com/classcode/t… 英文字母-1 个字节 汉字-3 个字节
-
在 Go 中,字符的本质是一个整数,直接输出时,是该字符对应的 UTF-8 编码的码值
-
可以直接给某个变量赋一个数字,然后按格式化输出时%c,会输出该数字对应的 unicode 字符
var a = 22269 fmt.Printf("a=%c", a) // 国 复制代码
-
字符类型是可以进行运算的,相当于一个整数,因为它都对应有 Unicode 码
var a = 'a' var b = 10 + a // 10 + 97 fmt.Printf("b=%c", b) // k 复制代码
字符类型本质探讨
- 字符型 存储到 计算机中,需要将字符对应的码值(整数)找出来 存储:字符--->对应码值---->二进制-->存储 读取:二进制----> 码值 ----> 字符 --> 读取
- 字符和码值的对应关系是通过字符编码表决定的(是规定好)
- Go 语言的编码都统一成了 utf-8。非常的方便,很统一,再也没有编码乱码的困扰了
四. 布尔型
- 布尔类型也叫 bool 类型,bool 类型数据只允许取值 true 和 false
- bool 类型占 1 个字节。
- bool 类型适于逻辑运算,一般用于程序流程控制
五. 字符串类型
字符串就是一串固定长度的字符连接起来的字符序列。Go 的字符串是由单个字节连接起来的。Go 语言的字符串的字节使用 UTF-8 编码标识 Unicode 文本
-
Go 语言的字符串的字节使用 UTF-8 编码标识 Unicode 文本,这样 Golang 统一使用 UTF-8 编码,中文乱码问题不会再困扰程序员
-
字符串一旦赋值了,字符串就不能修改了:在 Go 中字符串是不可变的
-
字符串的两种表示形式
-
双引号, 会识别转义字符
-
反引号,以字符串的原生形式输出,包括换行和特殊字符,可以实现防止攻击、输出源代码等效果
var name = "james\ncris" fmt.Print(name) var name = `james\ncris` fmt.Print(name) // james\ncris 复制代码
-
-
字符串拼接方式
var str = "james" + "cris" fmt.Print(str) // jamescris str += "---" fmt.Print(str) // jamescris--- 复制代码
六. 基本数据类型的默认值和转换
在 go 中,数据类型都有一个默认值,当程序员没有赋值时,就会保留默认值,在 go 中,默认值 又叫零值
数据类型 | 默认值 |
---|---|
整型 | 0 |
浮点型 | 0 |
字符串 | "" |
布尔类型 | false |
var a int
var b float64
var c bool
var str string
fmt.Printf("a=%v,b=%v,c=%v,d=%v", a, b, c, str)
复制代码
Golang 和 java / c 不同,Go 在不同类型的变量之间赋值时需要显式转换。也就是说 Golang 中数 据类型不能自动转换
表达式 T(v) 将值 v 转换为类型 T T: 就是数据类型,比如 int32,int64,float32 等等 v: 就是需要转换的变量
var a int16 = 200
var b = int8(a)
var c = float32(a)
// a = 200, b = -56, c = 200
fmt.Printf("a=%v,b=%v,c=%v", a, b, c)
复制代码
注意
- Go 中,数据类型的转换可以是从 表示范围小-->表示范围大,也可以 范围大--->范围小
- 被转换的是变量存储的数据(即值),变量本身的数据类型并没有变化!
var a int16 = 200
var b = float32(a)
// a:int16,b:float32
fmt.Printf("a:%T,b:%T", a, b)
复制代码
- 在转换中,比如将 int64 转成 int8 【-128---127】 ,编译时不会报错,只是转换的结果是按 溢出处理,和我们希望的结果不一样。 因此在转换时,需要考虑范围
七. 基本数据类型和 string 的转换(Printf 参数)
在 fmt.Printf() 方法中,常用的格式化参数:
%T : 表示变量的数据类型
%v : 直接输出变量的值
%c : byte 数据类型格式化
%q : 为字符串加上 ""
%t : 布尔格式化
%d : 整数格式化
%f : 浮点数格式化
基本数据类型转 String 方式一 fmt.Sprintf()
var num = 12
//1. 数字-->字符串
var str = fmt.Sprintf("%d", num)
// str=12,type is string
fmt.Printf("str=%v,type is %T", str, str)
var num = 123
var str = strconv.Itoa(num)
fmt.Printf("%q,%T", str, str)
//2. float-->字符串
var b = 11.1
str = fmt.Sprintf("%f", b)
// str=11.100000,type is string
fmt.Printf("str=%v,type is %T", str, str)
//3. bool-->字符串
var c = false
str = fmt.Sprintf("%t", c)
// str=false,type is string
fmt.Printf("str=%v,type is %T", str, str)
// str="false",type is string(使用 %q 可以为字符串加上 "")
fmt.Printf("str=%q,type is %T", str, str)
//4. char-->字符串
var d = 'a'
str = fmt.Sprintf("%c", d)
// str="a",type is string
fmt.Printf("str=%q,type is %T", str, str)
复制代码
基本数据类型转 String 方式二
使用 strconv 包的函数
var num = 123
// 10 表示 10 进制
var str = strconv.FormatInt(int64(num), 10)
fmt.Printf("str 类型是 %T,值是 %q", str, str)
var f = 12.2
// 'f' 表示格式 10表示小数位的精度, 64 表示64位float
str = strconv.FormatFloat(f, 'f', 10, 64)
// str 类型是 string,值是 "12.2000000000"
fmt.Printf("str 类型是 %T,值是 %q", str, str)
var b = false
str = strconv.FormatBool(b)
// str 类型是 string,值是 "false"
fmt.Printf("str 类型是 %T,值是 %q", str, str)
复制代码
String 转换为基本数据类型
var str = "true"
// 使用 _ 忽略返回的 error
var b, _ = strconv.ParseBool(str)
// true,bool
fmt.Printf("%t,%T", b, b)
str = "123"
var num, _ = strconv.ParseInt(str, 10, 64)
// 123,int64
fmt.Printf("%d,%T", num, num)
str = "12.2"
var f, _ = strconv.ParseFloat(str, 32)
// 12.200000,float64
fmt.Printf("%f,%T", f, f)
复制代码
ps : 如果 String 转换为基本数据类型,需要确保 String 可以有效转换成基本数据类型,例如 "hello" --> 数字(Go 处理为默认值,0)
3.5 指针
基本数据类型内存解析
-
基本数据类型,变量存的就是值,也叫值类型
-
获取变量的地址,用&,比如: var num int, 获取 num 的地址:&num 分析一下基本数据类型在内存的布局
var num = 12 // 0xc00006a080 fmt.Print(&num) 复制代码
-
指针类型,指针变量存的是一个地址,这个地址指向的空间存的才是值 比如:var ptr *int = &num
var num = 12 // 0xc0000120a8 fmt.Print(&num) // 输出:0xc0000120a8 // ptr 是一个指针变量 // ptr 的类型是 *int // ptr 指向的内存保存的是 num 的内存地址(ptr 指向的内存还有一个自己的内存) var ptr *int = &num fmt.Print(ptr) // 输出的是 ptr 的内存地址 : 0xc000096020 fmt.Println(&ptr) 复制代码
示意图如下
-
获取指针类型所指向的值,使用:*,比如 *ptr 获取 ptr 指向的内存所保存的另一块内存的值
var num = 12
// 0xc0000120a8
fmt.Print(&num)
// 输出:0xc0000120a8
// ptr 是一个指针变量
// ptr 的类型是 *int
// ptr 指向的内存保存的是 num 的内存地址(ptr 指向的内存还有一个自己的内存)
var ptr *int = &num
fmt.Print(ptr)
// 输出的是 ptr 的内存地址 : 0xc000096020
fmt.Println(&ptr)
// 输出 12
fmt.Println(*ptr)
复制代码
说明
- 值类型,都有对应的指针类型, 形式为 *数据类型,比如 int 的对应的指针就是 *int, float32 对应的指针类型就是 *float32, 依次类推
- 值类型包括:基本数据类型 int 系列, float 系列, bool, string 、数组和结构体 struct
3.6 值类型和引用数据类型
- 值类型:基本数据类型 int 系列, float 系列, bool, string 、数组和结构体 struct
- 引用类型:指针、slice 切片、map、管道 chan、interface 等都是引用类型
特点
-
值类型:变量直接存储值,内存通常在栈中分配
-
引用类型:变量存储的是一个地址,这个地址对应的空间才真正存储数据(值),内存通常在堆 上分配,当没有任何变量引用这个地址时,该地址对应的数据空间就成为一个垃圾,由 GC 来回收
3.7 标识符命名规范
- Golang 对各种变量、方法、函数等命名时使用的字符序列称为标识符
- 凡是自己可以起名字的地方都叫标识符
命名规则
-
由 26 个英文字母大小写,0-9 ,_ 组成
-
数字不可以开头。var num int //ok var 3num int //error
-
Golang 中严格区分大小写
- var num int
- var Num int
说明:在 golang 中,num 和 Num 是两个不同的变量
-
标识符不能包含空格
-
下划线"_"本身在 Go 中是一个特殊的标识符,称为空标识符。可以代表任何其它的标识符,但 是它对应的值会被忽略(比如:忽略某个返回值)。所以仅能被作为占位符使用,不能作为标识符使用
-
不能以系统保留关键字作为标识符(一共有 25 个),比如 break,if 等等...
注意事项
-
包名:保持 package 的名字和目录保持一致,尽量采取有意义的包名,简短,有意义,不要和 标准库不要冲突 fmt
-
变量名、函数名、常量名:采用驼峰法
举例: var stuName string = “tom” 形式: xxxYyyyyZzzz ...
-
如果变量名、函数名、常量名首字母大写,则可以被其他的包访问;如果首字母小写,则只能 在本包中使用 ( 注:可以简单的理解成,首字母大写是公开的,首字母小写是私有的) ,在 golang 没有 public , private 等关键字
包名从 src 目录下开始写
系统保留关键字
系统预定义标识符
4. Go 中的运算符
运算符是一种特殊的符号,用以表示数据的运算、赋值和比较等
-
算术运算符
-
赋值运算符
-
比较运算符/关系运算符
-
逻辑运算符
-
位运算符
-
其它运算符
4.1 算术运算符
算术运算符是对数值类型的变量进行运算的,比如:加减乘除。在 Go 程序中使用的非常多
示例代码
var a int = 12
var b int = 5
// 2(整数做除法,结果也是整数)
fmt.Println(a / b)
// 2(取余)
fmt.Println(a % b)
// 2.5
fmt.Println(10.0 / 4)
var c float32 = 10.0
// 5
fmt.Println(c / 2)
var n float32 = 2.5
// 变量浮点数之间的除法需要注意数据类型
var d = c / n
fmt.Print(d)
// % 的使用 : a % b = a-a/b*b
fmt.Println(10 % 4)
fmt.Println(-10 % 4)
fmt.Println(10 % -4)
fmt.Println(-10 % -4)
var i = 1
i++
fmt.Println("i=",i)
i--
fmt.Println("i=",i)
复制代码
细节
-
对于除号 "/",它的整数除和小数除是有区别的:整数之间做除法时,只保留整数部分而舍弃 小数部分。 例如: x := 19/5 ,结果是 3
-
当对一个数取模时,可以等价 a%b=a-a/b*b , 这样我们可以看到 取模的一个本质运算
-
Golang 的自增自减只能当做一个独立语言使用时,不能这样使用
var b = a++ var c := a-- 复制代码
-
Golang 的++ 和 -- 只能写在变量的后面,不能写在变量的前面,即:只有 a++ a-- 没有 ++a --a
-
Golang 的设计者去掉 c / java 中的 自增自减的容易混淆的写法,让 Golang 更加简洁,统一。(强制性的)
4.2 关系运算符
关系运算符的结果都是 bool 型,也就是要么是 true,要么是 false
关系表达式 经常用在 if 结构的条件中或循环结构的条件中
示例代码
var a = 1
var b = 2
fmt.Println(a > b)
fmt.Println(a == b)
fmt.Println(a < b)
复制代码
4.3 逻辑运算符
用于连接多个条件(一般来讲就是关系表达式),最终的结果也是一个 bool 值
示例代码
var a = 2
var b = 3
var c = 4
if a > b && b < c {
fmt.Println("true")
} else {
fmt.Println("false")
}
if a < b || b > c {
fmt.Println("ok")
} else {
fmt.Println("no ok")
}
复制代码
注意事项
- &&也叫短路与:如果第一个条件为 false,则第二个条件不会判断,最终结果为 false
- ||也叫短路或:如果第一个条件为 true,则第二个条件不会判断,最终结果为 true
func test() bool {
fmt.Println("test")
return true
}
func main() {
var a = 2
var b = 3
if a < b && test() {
fmt.Println("true")
} else {
fmt.Println("false")
}
if a < b || test() {
fmt.Println("ok")
} else {
fmt.Println("no ok")
}
}
复制代码
4.4 赋值运算符
赋值运算符就是将某个运算后的值,赋给指定的变量
二进制部分讲解
运算符优先级
4.5 位运算符
二进制部分讲解
4.6 其他运算符
注意 : Go不支持三元运算符
func main() {
var a = 3
// a的地址符号: 0xc00006a080
fmt.Println("a的地址符号:", &a)
var ptr *int = &a
// ptr 指向的值是: 3
fmt.Println("ptr 指向的值是:", *ptr)
}
复制代码
4.7 获取用户输入
在编程中,需要接收用户输入的数据,就可以使用键盘输入语句来获取。
案例说明
要求:可以从控制台接收用户信息,【姓名,年龄,薪水, 是否通过考试 】
-
使用 fmt.Scanln() 获取
func main() { var name string var age byte var flag bool fmt.Println("请输入用户名字") fmt.Scanln(&name) fmt.Println("请输入用户年龄") fmt.Scanln(&age) fmt.Println("是否通过考试") fmt.Scanln(&flag) fmt.Printf("用户名:%v,用户年龄:%v,用户是否通过考试:%v",name,age,flag) } 复制代码
-
使用 fmt.Scanf() 获取
func main() { var name string var age byte var flag bool fmt.Println("请输入你的名字,年龄以及是否通过考试,以空格分隔") fmt.Scanf("%s %d %t", &name, &age, &flag) fmt.Printf("用户名:%v,用户年龄:%v,用户是否通过考试:%v", name, age, flag) } 复制代码
5. 进制和位运算
进制介绍
在 golang 中,不能直接使用二进制来表示一个整数,它沿用了 c 的特点
简单示例
func main() {
var a = 011
var b = 2
var c = 0x11
// 10
fmt.Printf("%b\n", b)
// 2
fmt.Println("b", b)
// 9
fmt.Println("a", a)
// 17
fmt.Println("c", c)
}
复制代码
进制图示
进制转换
-
其他进制转换成二进制
二进制转换成十进制
八进制转换成十进制
十六进制转换成十进制
- 十进制转换成其他进制
十进制转成二进制
十进制转成八进制
十进制转成十六进制
-
二进制转其他进制
二进制转八进制
二进制转十六进制
-
其他进制转成二进制
八进制转成二进制
十六进制转成二进制
位运算
思考题
func main() {
var a = 1 >> 2
var b = -1 >> 2
var c = 1 << 2
var d = -1 << 2
// a 0 b -1 c 4 d -4
fmt.Println("a", a, "b", b, "c", c, "d", d)
}
复制代码
func main() {
// 2
fmt.Println(2 & 3)
// 3
fmt.Println(2 | 3)
// 5
fmt.Println(13 & 7)
// 5
fmt.Println(5 | 4)
// -2
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
示例图解
示例
a := 1 >> 2 // 0000 0001 =>0000 0000 = 0
c := 1 << 2 // 0000 0001 ==> 0000 0100 => 4