Go 语言保证了既能到达静态编译语言的安全和性能,又达到了动态语言开发维护的高效率 ,使用一个表达式来形容 Go 语言:Go = C + Python , 说明 Go 语言既有 C 静态语言程 序的运行速度,又能达到 Python 动态语言的快速开发。java
开发人员在为项目选择语言时,不得不在快速开发和性能之间作出选择。C和C++这类语言提供了很快的执行速度,而 Ruby 和 Python 这类语言则擅长快速开发。Go语言在这二者间架起了桥梁,不只提供了高性能的语言,同时也让开发更快速。c++
学习曲线平滑git
Go 语言自己包含类C语法、GC机制和经常使用工具,几乎支持大多数你在其余语言见过的特性:继承、重载、对象等.相比较其余语言(Java,c++), Go入门更加容易程序员
效率高github
Go拥有接近C的运行效率和接近PHP的开发效率,很符合当下软件开发迭代速度块,高性能,高效率的特色golang
静态类型语言,能够在编译的时候检查出来隐藏的大多数问题,又有动态语言的开发效率,有不少的包可使用,写起来的效率很高web
出身名门编程
Google公司汇集了一批牛人,在各类编程语言称雄争霸的局面下推出新的编程语言,天然有它的战略考虑。并且从Go语言的发展态势来看,Google对它这个新的宠儿仍是很看重的,Go天然有一个良好的发展前途.windows
自然支持并发数组
语言层面支持并发,这个就是Go最大的特点,天生的支持并发。能够充分的利用多核,很容易的实现并发
强大的标准库
包括互联网应用、系统编程和网络编程。Go里面的标准库基本上已是很是稳定了,特别是我这里提到的三个,网络层、系统层的库很是实用.而且Go提供了软件生命周期(开发、测试、部署、维护等等)的各个环节的工具,如go tool、gofmt、go test,最大限度确保 Go 程序的稳定性
常见的 Go 开发职位
这里参考 Go 的官网
docs.studygolang.com/doc/install
Cris 使用的是 Windows 平台,直接下载 msi 安装包便可
而后一路安装 next 便可
安装完毕后,打开 cmd,而后验证 Go 的安装
打开环境变量
打开 cmd 窗口
表示 Go 的开发环境ok
而后设置Go 的开发空间(推荐)
GOPATH 设置以下(表示Go 开发项目的放置路径)
这里我的选择 Visual Studio Code,毕竟以前开发的Python和Shell都使用的这个,感受至关好用
固然还能够选择 GoLand 等专门开发 Go 的 IDE
打开 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 项目开发路径整理
注意
关于 Go 的编译和执行
经常使用的转义字符
\t: 表示一个制表符,能够用于排版
\n: 换行符
\\ : \
\r: 回车, \r 后面的内容会依次替换前面的内容
package main
import "fmt"
func main() {
fmt.Println("cris")
fmt.Print("james\n")
fmt.Println("cirs\rhahah") // \r 表示回车但不换行
}
复制代码
// 行注释
/* 多行注释 */
复制代码
这里建议使用快捷键
设置每行代码长度
Golang 官方网站 golang.org
Golang 官方标准库 API 文档, golang.org/pkg(studygolang.com/pkgdoc) 能够查看 Golang 全部包下的函数和使用
Golang 中文网站 studygolang.com/
Dos: Disk Operating System 磁盘操做系统.一般在 windows 上程序员偶尔会经过命令的方式来操做系统,例如最多见的 CMD 窗口
dos 操做简单流程
经常使用 dos 命令
cd : 切换目录
cd .. : 切换到上一级目录
cd \ : 切换到根目录
dir : 查看当前目录
md 文件夹 : 新建一个文件夹
del 文件 : 删除文件
rd 空目录 : 删除空目录
rd /q/s 目录名 : 直接删除该目录及如下全部文件和目录
cp/move 文件 : 复制/移动文件
cls : 清屏
exit : 退出终端
建立空文件
追加/建立有内容的文件
变量表示内存中的一个存储区域
该区域有本身的名称(变量名)和类型(数据类型)
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
和 Java 相似,+ 左右两边都是数字,则相加;若是有两个字符串,则拼接
name, address := "james", "江北区"
name = name + "-harden" // james-harden
复制代码
基本数据类型
复杂数据类型
整数类型(有符号)
整数类型(无符号)
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 :
字符使用细节
字符常量是用单引号('')括起来的单个字符。例如: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 的字符串是由单个字节链接起来的。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)
复制代码
注意
var a int16 = 200
var b = float32(a)
// a:int16,b:float32
fmt.Printf("a:%T,b:%T", a, b)
复制代码
在 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)
基本数据类型内存解析
基本数据类型,变量存的就是值,也叫值类型
获取变量的地址,用&,好比: 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)
复制代码
说明
特色
值类型:变量直接存储值,内存一般在栈中分配
引用类型:变量存储的是一个地址,这个地址对应的空间才真正存储数据(值),内存一般在堆 上分配,当没有任何变量引用这个地址时,该地址对应的数据空间就成为一个垃圾,由 GC 来回收
命名规则
由 26 个英文字母大小写,0-9 ,_ 组成
数字不能够开头。var num int //ok var 3num int //error
Golang 中严格区分大小写
说明:在 golang 中,num 和 Num 是两个不一样的变量
标识符不能包含空格
下划线"_"自己在 Go 中是一个特殊的标识符,称为空标识符。能够表明任何其它的标识符,但 是它对应的值会被忽略(好比:忽略某个返回值)。因此仅能被做为占位符使用,不能做为标识符使用
不能以系统保留关键字做为标识符(一共有 25 个),好比 break,if 等等...
注意事项
包名:保持 package 的名字和目录保持一致,尽可能采起有意义的包名,简短,有意义,不要和 标准库不要冲突 fmt
变量名、函数名、常量名:采用驼峰法
举例: var stuName string = “tom” 形式: xxxYyyyyZzzz ...
若是变量名、函数名、常量名首字母大写,则能够被其余的包访问;若是首字母小写,则只能 在本包中使用 ( 注:能够简单的理解成,首字母大写是公开的,首字母小写是私有的) ,在 golang 没有 public , private 等关键字
包名从 src 目录下开始写
系统保留关键字
系统预约义标识符
运算符是一种特殊的符号,用以表示数据的运算、赋值和比较等
算术运算符
赋值运算符
比较运算符/关系运算符
逻辑运算符
位运算符
其它运算符
算术运算符是对数值类型的变量进行运算的,好比:加减乘除。在 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 更加简洁,统一。(强制性的)
关系运算符的结果都是 bool 型,也就是要么是 true,要么是 false
关系表达式 常常用在 if 结构的条件中或循环结构的条件中
示例代码
var a = 1
var b = 2
fmt.Println(a > b)
fmt.Println(a == b)
fmt.Println(a < b)
复制代码
用于链接多个条件(通常来说就是关系表达式),最终的结果也是一个 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")
}
复制代码
注意事项
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")
}
}
复制代码
赋值运算符就是将某个运算后的值,赋给指定的变量
二进制部分讲解
运算符优先级
二进制部分讲解
注意 : Go不支持三元运算符
func main() {
var a = 3
// a的地址符号: 0xc00006a080
fmt.Println("a的地址符号:", &a)
var ptr *int = &a
// ptr 指向的值是: 3
fmt.Println("ptr 指向的值是:", *ptr)
}
复制代码
在编程中,须要接收用户输入的数据,就可使用键盘输入语句来获取。
案例说明
要求:能够从控制台接收用户信息,【姓名,年龄,薪水, 是否经过考试 】
使用 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)
}
复制代码
进制介绍
在 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 个位运算, 分别是”按位与&、按位或|、按位异或^,它们的运算规则是:
示例图解
示例
a := 1 >> 2 // 0000 0001 =>0000 0000 = 0
c := 1 << 2 // 0000 0001 ==> 0000 0100 => 4