赞
踩
1基础搭建
1.1,安装vscode https://code.visualstudio.com/download 64位
1.2,Windows 下搭建Go 开发环境-安装和配置 SDK
SDK 的全称(Software Development Kit 软件开发工具包)
Go 语言的官网为:golang.org , 因为各种原因,可能无法访问
SDK 下载地址:Golang 中国 https://www.golangtc.com/download。
选择对应的 sdk 版本
Windows 下:根据自己系统是 32 位还是 64 位进行下载:
32 位系统:go1.9.2.windows-386.zip
64 位系统:go1.9.2.windows-amd64.zip
如何测试我们的 go 的 sdk 安装成功。
windows 下配置 Golang 环境变量:
1.3,Linux 下搭建 Go 开发环境-安装和配置 SDK
Linux 下 SDK 的各个版本说明:
Linux 下:根据系统是 32 位还是 64 位进行下载:
32 位系统:go1.9.2.linux-386.tar.gz
64 位系统:go1.9.2.linux-amd64.tar.gz
如何确认你的 linux 是多少位
请注意:安装路径不要有中文或者特殊符号如空格等
SDK 安装目录建议: linux 放在 /opt 目录下
安装时,解压即可,我们使用的是 tar.gz
步骤 1: 将 go1.9.2.linux-amd64.tar.gz 传输到 ubuntu
步骤 2: 将 go1.9.2.linux-amd64.tar.gz 拷贝到 /opt 下
步骤 3: cd /opt
步骤 4:tar -zxvf go1.9.2.linux-amd64.tar.gz [解压后,就可以看到一个 go 目录]
步骤 5: cd go/bin
步骤 6:./go version
Linux 下配置 Golang 环境变量
步骤 1:使用 root 的权限来编辑 vim /etc/profile 文件
步骤 2: 如果需要生效的话,需要注销一下(重新登录),再使用
2,语法学习
2.1,Println 输出 “hello,world”
对上图的说明
1)go 文件的后缀是 .go
2) package main
表示该 hello.go 文件所在的包是 main, 在 go 中,每个文件都必须归属于一个包。
3) import “fmt”
表示:引入一个包,包名 fmt, 引入该包后,就可以使用 fmt 包的函数, 比如:fmt.Println
4) func main() {
}
func 是一个关键字,表示一个函数。
main 是函数名,是一个主函数,即我们程序的入口。
fmt.Println(“hello”)
表示调用 fmt 包的函数 Println 输出 “hello,world”
通过 go build 命令对该 go 文件进行编译,生成 .exe 文件.
运行 hello.exe 文件即可
注意:通过 go run 命令可以直接运行 hello.go 程序 [类似执行一个脚本文件的形式]
2.2,Golang 执行流程分析
如果是对源码编译后,再执行,Go 的执行流程如下图
如果我们是对源码直接 执行 go run 源码,Go 的执行流程如下图
2.3, 编译和运行说明
1)有了 go 源文件,通过编译器将其编译成机器可以识别的二进制码文件。
2)在该源文件目录下,通过 go build 对 hello.go 文件进行编译。可以指定生成的可执行文件名,在
windows 下 必须是 .exe 后缀。
3) 如果程序没有错误,没有任何提示,会在当前目录下会出现一个可执行文件(windows 下是.exe Linux 下是一个可执行文件),该文件是二进制码文件,也是可以执行的程序。
4) 如果程序有错误,编译时,会在错误的那行报错。有助于程序员调试错误.
5) 运行有两种形式
2.4,
2.4.1
Golang 官方标准库 API 文档, https://golang.org/pkg
Golang 中文网 在线标准库文档: Go语言标准库文档中文版 | Go语言中文网 | Golang中文社区 | Golang中国
Golang 程序编写的规则:
1),go 文件的后缀 .go
2),go 程序区分大小写
3),go 的语句后,不需要带分号
4), go 定义的变量,或者 import 包,必须使用,如果没有使用就会报错
5), go 中,不要把多条语句放在同一行。否则报错
2.4.2 Golang 变量和语法
第一种:指定变量类型,声明后若不赋值,使用默认值
第二种:根据值自行判定变量类型(类型推导)
第三种:省略 var, 注意 :=左侧的变量不应该是已经声明过的,否则会导致编译错误
多变量声明
在编程中,有时我们需要一次性声明多个变量,Golang 也提供这样的语法
如何一次性声明多个全局变量【在 go 中函数外部定义变量就是全局变量】
该区域的数据值可以在同一类型范围内不断变化(重点)
变量在同一个作用域(在一个函数或者在代码块)内不能重名
变量=变量名+值+数据类型,这一点请大家注意,变量的三要素
Golang 的变量如果没有赋初值,编译器会使用默认值, 比如 int 默认值 0 string 默认值为空串,小数默认为 0
变量的声明,初始化和赋值
数据类型的基本介绍:
整数的各个类型
int 的无符号的类型:
int 的其它类型的说明:
整型的使用细节:
Golang 各整数类型分:有符号和无符号,int uint 的大小和系统有关
Golang 的整型默认声明为 int 型
如何在程序查看某个变量的字节大小和数据类型 (使用较多)
Golang 程序中整型变量在使用时,遵守保小不保大的原则,即:在保证程序正确运行下,尽量使用占用空间小的数据类型。【如:年龄】
bit: 计算机中的最小存储单位。byte:计算机中基本存储单元。[二进制再详细说] 1byte = 8 bit
小数类型/浮点型
关于浮点数在机器中存放形式的简单说明,浮点数=符号位+指数位+尾数位说明:浮点数都是有符号的
尾数部分可能丢失,造成精度损失。 -123.0000901
说明: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 的字符串不同,它是由字节组成的
1)字符常量是用单引号('')括起来的单个字符。例如:var c1 byte = 'a' var c2 int = '中' var c3 byte = '9'
2)Go 中允许使用转义字符 '\’来将其后的字符转变为特殊字符型常量。例如:var c3 char = ‘\n’
// '\n'表示换行符
3)Go 语 言 的 字 符 使 用 UTF-8 编 码 , 如 果 想 查 询 字 符 对 应 的 utf8 码 值
英文字母-1 个字节 汉字-3 个字节
4)在 Go 中,字符的本质是一个整数,直接输出时,是该字符对应的 UTF-8 编码的码值。
5)可以直接给某个变量赋一个数字,然后按格式化输出时%c,会输出该数字对应的 unicode 字符
字符类型是可以进行运算的,相当于一个整数,因为它都对应有 Unicode 码
布尔类型
bool 类型占 1 个字节
string 类型
字符串就是一串固定长度的字符连接起来的字符序列。Go 的字符串是由单个字节连接起来的。Go语言的字符串的字节使用 UTF-8 编码标识 Unicode 文本
Go 语言的字符串的字节使用 UTF-8 编码标识 Unicode 文本,这样 Golang 统一使用 UTF-8 编码,中文乱码问题不会再困扰程序员
字符串一旦赋值了,字符串就不能修改了:在 Go 中字符串是不可变的
字符串拼接方式
当一行字符串太长时,需要使用到多行字符串,可以如下处理
基本数据类型的默认值
基本数据类型的相互转换
表达式 T(v) 将值 v 转换为类型 T
T: 就是数据类型,比如 int32,int64,float32 等等
v: 就是需要转换的变量
在转换中,比如将 int64 转成 int8 【-128---127】 ,编译时不会报错,只是转换的结果是按溢出处理,和我们希望的结果不一样。 因此在转换时,需要考虑范围
基本数据类型和string 的转换
在程序开发中,我们经常将基本数据类型转成 string,或者将 string 转成基本数据类型
方式 1:fmt.Sprintf("%参数", 表达式) 【个人习惯这个,灵活】
函数的介绍:
参数需要和表达式的数据类型相匹配
fmt.Sprintf().. 会返回转换后的字符串
方式 2:使用 strconv 包的函数
string 类型转基本数据类型
使用时 strconv 包的函数
string 转基本数据类型的注意事项
在将 String 类型转成 基本数据类型时,要确保 String 类型能够转成有效的数据,比如 我们可以把 "123" , 转成一个整数,但是不能把 "hello" 转成一个整数,如果这样做,Golang 直接将其转成 0 ,其它类型也是一样的道理. float => 0 bool => false
2.5 指针
分析一下基本数据类型在内存的布局.
指针类型,指针变量存的是一个地址,这个地址指向的空间存的才是值
比如:var ptr *int = &num
举例说明:指针在内存的布局.
获取指针类型所指向的值,使用:*,比如:var ptr *int, 使用*ptr 获取 ptr 指向的值
值类型,都有对应的指针类型, 形式为 *数据类型,比如 int 的对应的指针就是 *int, float32
对应的指针类型就是 *float32, 依次类推。
值类型包括:基本数据类型 int 系列, float 系列, bool, string 、数组和结构体 struct
值类型:基本数据类型 int 系列, float 系列, bool, string 、数组和结构体 struct
引用类型:指针、slice 切片、map、管道 chan、interface 等都是引用类型
值类型:变量直接存储值,内存通常在栈中分配示意图:
引用类型:变量存储的是一个地址,这个地址对应的空间才真正存储数据(值),内存通常在堆上分配,当没有任何变量引用这个地址时,该地址对应的数据空间就成为一个垃圾,由 GC 来回收
示意图:
内存的栈区和堆区示意图
系统保留关键字
系统的预定义标识符
算术运算符的使用
位运算符
其它运算符说明
键盘输入语句
要求:可以从控制台接收用户信息,【姓名,年龄,薪水, 是否通过考试 】
使用 fmt.Scanln() 获取
使用 fmt.Scanf() 获取
原码、反码、补码
位运算符和移位运算符
Golang 中有 2 个移位运算符:
>>、<< 右移和左移,运算规则:
右移运算符 >>:低位溢出,符号位不变,并用符号位补溢出的高位
左移运算符 <<: 符号位不变,低位补 0
for 循环
方式1传统方式
方式2 for - range
如果我们的字符串含有中文,那么传统的遍历字符串方式,就是错误,会出现乱码。原因是传统的对字符串的遍历是按照字节来遍历,而一个汉字在 utf8 编码是对应 3 个字节。
如何解决 需要要将 str 转成 []rune 切片.=> 体验一把
对应 for-range 遍历方式而言,是按照字符方式遍历。因此如果有字符串有中文,也是 ok
2.4.3 函数 包
包使用的注意事项和细节讨论
1),在给一个文件打包时,该包对应一个文件夹,比如这里的 utils 文件夹对应的包名就是 utils,
文件的包名通常和文件所在的文件夹名一致,一般为小写字母
2)当一个文件要使用其它包函数或变量时,需要先引入对应的包
引入方式 1:import "包名"
引入方式 2:
import (
"包名"
"包名"
)
package 指令在 文件第一行,然后是 import 指令
在 import 包时,路径从 $GOPATH 的 src 下开始,不用带 src , 编译器会自动从 src 下开始引入
3)为了让其它包的文件,可以访问到本包的函数,则该函数名的首字母需要大写,类似其它语言的 public ,这样才能跨包访问。比如 utils.go 的
4)在访问其它包函数,变量时,其语法是 包名.函数名, 比如这里的 main.go 文件中
5)如果包名较长,Go 支持给包取别名, 注意细节:取别名后,原来的包名就不能使用了
说明: 如果给包取了别名,则需要使用别名来访问该包的函数和变量
6)在同一包下,不能有相同的函数名(也不能有相同的全局变量名),否则报重复定义
7)如果你要编译成一个可执行程序文件,就需要将这个包声明为 main , 即 package main .这个就是一个语法规范,如果你是写一个库 ,包名可以自定义
return 语句
案例演示 1
请编写要给函数,可以计算两个数的和和差,并返回结果。
案例演示 2
一个细节说明: 希望忽略某个返回值,则使用 _ 符号表示占位忽略
函数使用的注意事项和细节讨论
1)函数的形参列表可以是多个,返回值列表也可以是多个。
2)形参列表和返回值列表的数据类型可以是值类型和引用类型。
3)函数的命名遵循标识符命名规范,首字母不能是数字,首字母大写该函数可以被本包文件和其它包文件使用,类似 public , 首字母小写,只能被本包文件使用,其它包文件不能使用,类似 privat
4)函数中的变量是局部的,函数外不生效【案例说明】
5)基本数据类型和数组默认都是值传递的,即进行值拷贝。在函数内修改,不会影响到原来的值。
6)如果希望函数内的变量能修改函数外的变量(指的是默认以值传递的方式的数据类型),可以传入变量的地址&,函数内以指针的方式操作变量。从效果上看类似引用
7)Go 函数不支持函数重载
8)在 Go 中,函数也是一种数据类型,可以赋值给一个变量,则该变量就是一个函数类型的变量了。通过该变量可以对函数调用
9)函数既然是一种数据类型,因此在 Go 中,函数可以作为形参,并且调用
10)为了简化数据类型定义,Go 支持自定义数据类型
基本语法:type 自定义数据类型名 数据类型 // 理解: 相当于一个别名
案例:type myInt int // 这时 myInt 就等价 int 来使用了.
案例:type mySum func (int, int) int // 这时 mySum 就等价 一个 函数类型 func (int, int)
举例说明自定义数据类型的使用:
11)支持对函数返回值命名
12)使用 _ 标识符,忽略返回值
13)Go 支持可变参数
(3) 如果一个函数的形参列表中有可变参数,则可变参数需要放在形参列表最后。代码演示:
init 函数:
每一个源文件都可以包含一个 init 函数,该函数会在 main 函数执行前,被 Go 运行框架调用,也就是说 init 会在 main 函数前被调用
inti 函数的注意事项和细节
1)如果一个文件同时包含全局变量定义,init 函数和 main 函数,则执行的流程全局变量定义->init函数->main 函数
2)init 函数最主要的作用,就是完成一些初始化的工作,比如下面的案例
匿名函数:
Go 支持匿名函数,匿名函数就是没有名字的函数,如果我们某个函数只是希望使用一次,可以考虑使用匿名函数,匿名函数也可以实现多次调用。
匿名函数使用方式 1
在定义匿名函数时就直接调用,这种方式匿名函数只能调用一次。 【案例演示】
匿名函数使用方式 2
将匿名函数赋给一个变量(函数变量),再通过该变量来调用匿名函数 【案例演示】
全局匿名函数
如果将匿名函数赋给一个全局变量,那么这个匿名函数,就成为一个全局匿名函数,可以在程序有效。
闭包
基本介绍:闭包就是一个函数和与其相关的引用环境组合的一个整体(实体)
对上面代码的说明和总结
1)AddUpper 是一个函数,返回的数据类型是 fun (int) int
2)闭包的说明
返回的是一个匿名函数, 但是这个匿名函数引用到函数外的n ,因此这个匿名函数就和n 形成一个整体,构成闭包。
3) 大家可以这样理解: 闭包是类, 函数是操作,n 是字段。函数和它使用到 n 构成闭包。
4)当我们反复的调用 f 函数时,因为 n 是初始化一次,因此每调用一次就进行累计。
5)我们要搞清楚闭包的关键,就是要分析出返回的函数它使用(引用)到哪些变量,因为函数和它引用到的变量共同构成闭包
6)对上面代码的一个修改,加深对闭包的理解
字符串常用的系统函数
说明:字符串在我们程序开发中,使用的是非常多的,常用的函数需要同学们掌握[带看手册或者官方编程指南]:
1)统计字符串的长度,按字节 len(str)
2)字符串遍历,同时处理有中文的问题 r := []rune(str)
3)字符串转整数: n, err := strconv.Atoi("12")
4)整数转字符串 str = strconv.Itoa(12345)
5)字符串 转 []byte: var bytes = []byte("hello go")
6)[]byte 转 字符串: str = string([]byte{97, 98, 99})
7) 10 进制转 2, 8, 16 进制: str = strconv.FormatInt(123, 2) // 2-> 8 , 16
8)查找子串是否在指定的字符串中: strings.Contains("seafood", "foo") //true
9)统计一个字符串有几个指定的子串 : strings.Count("ceheese", "e") //4
10)不区分大小写的字符串比较(== 是区分字母大小写的): fmt.Println(strings.EqualFold("abc", "Abc")) // true
11)返回子串在字符串第一次出现的 index 值,如果没有返回-1 : strings.Index("NLT_abc", "abc") // 4
12)返回子串在字符串最后一次出现的 index,如没有返回-1 : strings.LastIndex("go golang", "go")
13)将指定的子串替换成 另外一个子串: strings.Replace("go go hello", "go", "go 语言", n) n 可以指定你希望替换几个,如果 n=-1 表示全部替换
14)按 照 指 定 的 某 个 字 符 , 为 分 割 标 识 , 将 一 个 字 符 串 拆 分 成 字 符 串 数 组 :
strings.Split("hello,wrold,ok", ",")
15)将字符串的字母进行大小写的转换: strings.ToLower("Go") // go strings.ToUpper("Go") // GO
16)将字符串左右两边的空格去掉: strings.TrimSpace(" tn a lone gopher ntrn ")
17)将字符串左右两边指定的字符去掉 : strings.Trim("! hello! ", " !") // ["hello"] //将左右两边 !
和 " "去掉
18)将字符串左边指定的字符去掉 : strings.TrimLeft("! hello! ", " !") // ["hello"] //将左边 ! 和 " "去掉
19)将字符串右边指定的字符去掉 : strings.TrimRight("! hello! ", " !") // ["hello"] //将右边 ! 和 " "去掉
20)判断字符串是否以指定的字符串开头: strings.HasPrefix("ftp://192.168.10.1", "ftp") // true
21)判断字符串是否以指定的字符串结束: strings.HasSuffix("NLT_abc.jpg", "abc") //false
时间和日期相关函数
如何获取到其它的日期信息
方式 1: 就是使用 Printf 或者 SPrintf
方式二: 使用 time.Format() 方法完成:
内置函数
1)len:用来求长度,比如 string、array、slice、map、channel
2)new:用来分配内存,主要用来分配值类型,比如 int、float32,struct...返回的是指针举例说明 new 的使用:
上面代码对应的内存分析图:
24.4,数组与切片
数组的定义
var 数组名 [数组大小]数据类型
var a [5]int
赋初值 a[0] = 1 a[1] = 30 ....
1)数组的地址可以通过数组名来获取 &intArr
2)数组的第一个元素的地址,就是数组的首地址
3)数组的各个元素的地址间隔是依据数组的类型决定,比如 int64 -> 8 int32->4...
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。