1 go介绍
# 1 Go 即Golang
是Google公司2009年11月正式对外公开的一门编程语言
好多公司:python+go混用, 架构师: 前端、运维、测试、后端各种语言
真正发展也就7、8年时间,很新,云原生的火 ---> docker,k8s
Go上有些坑 --->一直在发展: 支持泛型
# python 1989年 java 1990年
# 2 go类型特征
Go是静态 强类型 的编译型语言,是区别于解释型语言的弱类型语言
# 静态:类型固定 强类型:不同类型不允许直接运算 # 若需要不同类型运算,需要先 强制类型转换
# python 是动态 强类型语言
# 3 解释型与编译型
编译型:java、c、c++、c#、go 等
解释型:python、js、php 等
# 编译型:涉及到跨平台问题,因为它需要编译成该平台的可执行文件
c、c++ : 不支持跨平台,需要在不同平台 编译成可执行文件再执行
java : 号称跨平台,java字节码运行在虚拟机(jvm)上,需在不同平台装虚拟机(或jdk)
go : 跨平台编译、交叉编译,可在windows平台上编译成linux/mac的可执行文件 在mac上可执行、部署
# 部署、执行
java: 编译成字节码文件 ---> 需要装jdk,运行在jvm上 ---> 运行
go : 编译成可执行文件 ---> 运行
# 解释型:不存在跨平台问题,有解释器
python、php、nodejs :天然跨平台(解释器跨平台), 运行在解释器上,需在不同平台上装解释器
# 部署、执行
php、python: 安装各自解释器 ---> 安装所需模块 ---> 运行
# python文件 也可以打包成可执行文件exe
# 4 Go特性
跨平台的编译型语言、交叉编译
管道(channel)、切片(slice)、并发(routine)
有垃圾回收的机制
支持面向对象和面向过程的编程模式 # go的面向对象没有类的概念
# 5 发展(go是用c写起来的)
2009年11月7日 weekly.2009-11-06 # 早期的版本
2015年8月19日 go 1.5
实现的架构变化,同时保留了和旧版本的兼容性,本次更新中移除了"最后残余的C代码"。
# 从此以后,自举,自己写自己
2018年8月24日 go 1.11 # 增加包管理 go module测试
2020年2月 go 1.14 # 包管理用于实际生产环境
# 6 Go语言应用
中国的互联网公司基本都会用,有些没用的,都在准备用
# eg: docker、k8s、蓝鲸、百度 小米:falcon
# 7 应用领域 go适合做什么
-服务端开发,微服务开发、并发、分布式等 运维相关,区块链,云平台
-第一款开源区块链产品是用go写的
# 8 Go语言发展前景,为什么火
很新,生态不完善
云计算和区块链的火,互联网企业高并发的需求
2 开发环境搭建
# 1 开发环境: SDK
下载:https://golang.google.cn/dl/
1.17.x ---> 一路下一步 # 自动把安装路径加入到环境变量
# 测试安装成功
go version # 查看版本
# 2 集成开发环境: IDE
goland # 学习用的话,为了使用 IDE Eval Reset的插件激活,采用版本:2021.2.3
https://download.jetbrains.com/go/goland-2022.2.2.exe?_ga=2.17296255.772214039.1675656980-1569158920.1640582407&_gl=1*11rb9vm*_ga*MTU2OTE1ODkyMC4xNjQwNTgyNDA3*_ga_9J976DJZ68*MTY3NTY1Njk4MC4yLjEuMTY3NTY2MDM5OS4wLjAuMA..
# 推荐用jetbrains全家桶 goland、pycharm、idea、androidstudio(安卓开发)
3 基本命令、注意事项
# 1 goland创建项目(两种模式--管理包的导入)
-Go:选择go的安装路径(默认选中了) # 默认采用go module模式导入包 统一采用这种
-Go(GOPATH):所有的go代码(源码)必须放在该路径下的src文件夹下,否则无法执行 # 基本弃用
# 默认创建到:用户家目录下的go文件夹(mac,windows,linux)
-src : 源码(包含第三方的和自己项目的)
-bin : 编译生成的可执行程序
-pkg : 编译时生成的中间缓存文件
# 创建项目路径,go文件都不要出现中文
# 2 go基本命令
### 必须记住的
go env # go的环境变量
GO111MODULE=空的 # 是否开启go module模式 新版本默认都是开启的
GOPROXY=https://goproxy.cn,direct # 下载go模块的地址
GOPATH=C:\Users\oldboy\go # 若使用go path模式,所有代码必须放在该文件夹的src路径下
GOROOT=c:\go # go sdk的安装路径
go build 文件名.go # 编译 编译型语言,需要先编译成可执行文件,再执行
# eg: go build s1.go
go run 文件名.go # 编译并执行 常开发阶段用 在goland中,右键-运行即可
# eg: go run s1.go 编译到哪里去了?用完就删了
### 其他
go get # 下载并安装包和依赖 等同于pip install
go version # 版本信息
go fmt # 运行gofmt进行格式化 go fmt:自动将代码格式
# 3 go注释
// 单行注释
/*
多行注释
多行注释
*/
# 4 go文件编写-注意事项 重点
go(所有编译型语言)项目要运行,必须有一个入口
go的入口是main包下的main函数
# main包下 不可以有多个main函数
# 5 win上编译出不同平台可执行
# Mac
SET CGO_ENABLED=0
SET GOOS=darwin
SET GOARCH=amd64
go build filename.go
# Linux
SET CGO_ENABLED=0
SET GOOS=linux
SET GOARCH=amd64
go build filename.go
# 6 导入包
1.在代码中 import "fmt",从哪导入? # 标准库的包,就是从环境变量中的go root的src路径下
2.可能会有第三方包,采用的是go path模式 # 导入路径就从go path的src路径下开始算
# 7 go代码 跟缩进无关
4 hello world
package main //声明包名为main 每一个go文件都属于某个包
import "fmt" //导入内置包fmt 从哪导入? 就是从环境变量中的go root的src路径下
func main() { //定义了一个main函数,大括号包裹是函数体的内容
fmt.Println("hello world") //打印函数等同与print()
}
//编译
go build s1.go //编译成s1.exe
//执行
s1.exe
//编译并执行 在goland中,右键-运行即可
go run s1.go
5 命名规范
# 命令规范:
-文件命名:尽量用下划线 python用下划线
-变量命名:推荐用驼峰 python用下划线
-关键字和保留字不能作为变量名
# Go语言中有25个关键字 关键字不能用于自定义名字,只能在特定语法结构中使用
break default func interface select
case defer go map struct
chan else goto package switch
const fallthrough if range type
continue for import return var
# go语言中有37个保留字,主要对应内建的常量、类型和函数
内建常量: true false iota nil
内建类型: int int8 int16 int32 int64
uint uint8 uint16 uint32 uint64 uintptr
float32 float64 complex128 complex64
bool byte rune string error
内建函数: make len cap new append copy close delete
complex real imag
panic recover
# 关键字:goto 跳转到特定语句 最好不要使用,引起逻辑混乱
python中没有 go、c都有goto
java中作为了保留关键字,但是没有作用
6 变量
//总结:
1 变量类型在定义阶段就确定了,一旦确定,不允许改变
2 变量不可以重复定义
3 变量要先定义再使用
4 变量定义了必须使用,否则报错
5 强类型,不同类型之前不能直接运算(强制类型转换)
package main
import "fmt"
func main() {
//1 完整定义: var关键字 变量名 变量类型 = 变量值
var age int = 10 //在go中,变量定义了就必须使用,如果不使用就报错
fmt.Println(age)
//2 类型推导: 类型不需要写了 但并不是没有类型,而是推导出来的
var age =10 //定义并赋初值
age=100 //修改值
var name ="lqz"
fmt.Println(age) //打印并换行
fmt.Print(name) //打印不换行
//3 简略声明: 冒号和等号是一家,类型和var关键字都不写 使用较多
a:=10
fmt.Println(a)
//4 其他变形方式
//4.1 只定义不赋值 有个默认值
var age int //定义 //如果是只定义不赋值,只能用这种,不能使用类型推导和简略声明
age=99 //赋初值
fmt.Println(age) //使用
//4.2 声明多个变量
var width,height int = 100, 50 //完整定义形式
var width,height =100,50 //类型推导形式
var width,height =100,"lqz"
width,height :=100,";qz" //简略声明形式
var name,age,hobby string,int,string="lqz",99,"篮球" //这个不行,若指定类型,必须为同一类型
//4.3 声明多个变量,并赋初值 常用这种
var (
name = "naveen"
age int = 29
height int
)
fmt.Println(name,age,height)
//4.4 小坑
var a int =10
b,a:=99,100 //这个不报错,我们觉得a是重复定义
//但冒号左侧,只要有一个没有定义过的变量,就可以
fmt.Println(b)
fmt.Print(a)
}
5 基础数据类型
# 基础数据类型
# 数字:
-有符号整型 包含负整数
-int : 分平台,在32位机器是int32,在64位机器是int64
-int8 : 8个比特位 表示整数范围是:+-2的7次方-1 -127到127 包含0
# 8个bit是1byte
-int16 : 16个比特位 +-2的15次方减一
-int32 : 32个比特位
-int64 : 64个比特位
-无符号整型 正整数类型
-uint : 分平台,在32位平台是uint32,在64位平台上是uint64
-uint8 : 0--2的8次方-1 定义一个人的年龄
-uint16 : 0--2的16次方-1
-uint32 : 0--2的32次方-1
-uint64 : 0--2的64次方-1
-浮点型(小数) 表示小数点后长度多少位
-float32 : 7位
-float64 : 15位
-复数 实部和虚部
-complex64
-complex128
-byte 与 rune 表示字符对应的两种编码的数字多少 # 单引号包裹
byte : 是uint8的别名 1个byte 刚好是ASCII编码的大小
rune : 是int32的别名 4个byte 刚好是utf-8编码的大小
# 字符串
双引号包裹 " "
反引号包裹 ` ` # 可以用来包裹 带 ""的字符串、换行等
# 布尔
true 和 false
# 数据类型的默认值(零值):
数字类型 : 0
字符串类型 : 空字符串
布尔类型 : false
# Java的数字类型
byte : int8 8位,最大存储数据量是255,数据范围是-128~127之间
short : int16 16位,最大数据存储量是65536,数据范围是-32768~32767之间
int : int32 32位,最大数据存储容量是2的32次方减1,数据范围是-2的31次方到2的31次方减1
long : int64 64位,最大数据存储容量是2的64次方减1,数据范围为-2的63次方到2的63次方减1
float : float32 32位,数据范围在3.4e-45~1.4e38,直接赋值时必须在数字后加上f或F
double: float64 64位,数据范围在4.9e-324~1.8e308,赋值时可以加d或D也可以不加
6 常量
//常量:在程序运行过程中不会被改变,定义并赋初值以后,再也不变了
package main
import "fmt"
//常量的定义
func main() {
//第一种: 完整定义
const 变量名 变量类型 = 变量值
const age int8 = 99
age=199 // 修改就报错
fmt.Println(age)
//第二种: 类型推导
const age = 99
age=88 // 修改就报错
fmt.Println(age)
//其他定义: 定义多个常量
const name,age = "zhangsan",99
const (
name string ="lqz"
age =99
)
const (
a = 10 //10
b //10
c = 6 //6
d //6
e =iota //4
f //5
)
fmt.Println(s1,s2,s3,s4,s5)
}
// 总结:
1.const 关键字定义常量,不允许改变
2.定义常量时,第一行必须赋值;若从第二行开始不赋值,则以上一行为基准,以后都是这个值
3.iota的用法: 以行为基准,从0开始,iota放在第几行,就是行数-1,再往后不赋值,都会自增1
4.iota用的最多的情况,就是放在第一行,后面都不用赋值,会自增