1.https://studygolang.com/dl
安装包
2.https://goproxy.cn/
国内镜像
$ go env -w GO111MODULE=on
$ go env -w GOPROXY=https://goproxy.cn,direct
3.配置GOPATH
go的代码必须在GOPATH中,也就是一个工作目录,目录包含三个子目录
$GOPATH
src 存放go源代码的目录,存放golang项目的目录,所有项目都放到gopath的src目录下
bin 在go install后生成的可执行文件的目录
pkg 编译后生成的,源码文件,如.a
4.ide
goland/idea
vscode+go插件
go mod 配置
快捷键 删除行/前进,后退/转到定义
// 一个module只能有一个main入口 main函数所在的包名必须是main
package main
import "fmt"
// 函数以func开头,函数体开头的{必须在函数头所在行尾部,不能单独起一行 即 func { 不能 func \r\n {
func main() {
// 每个语句最后的;可以省略
fmt.Printf("htllo world\n")
// 字符串字面量用双引号
}
GO编译 生成可执行文件
go build hello.go // 在windows下编程exe可执行文件
运行
hello
或者go run hello.go 直接运行
go tool compile -l -N -S xxx.go > xxx.s
-S产生汇编代码 -N禁用优化 -l禁用内联
python和java源码需要解释器/虚拟机编译成二进制
go源码直接编译成二进制 部署简单
25个关键字
var和const :变量和常量的声明
var varName type 或者 varName : = value
package and import: 导入
func: 用于定义函数和方法
return :用于从函数返回
defer someCode :在函数退出之前执行 延迟执行
go : 用于并行 并发语法糖关键字
复合数据结构:
interface 用于定义接口
struct 用于定义抽象数据类型
chan用于channel通讯
map用于声明map类型数据
控制程序结构:
break、case、continue、for、fallthrough、else、if、switch、goto、default 流程控制
type用于声明自定义类型
select 用于选择不同类型的通讯
range用于读取slice、map、channel数据
变量使用
var 变量名 变量类型
如: 不赋值 默认 a 0 s''
var a int
var s string
var a, b int = 1, 2 // 多个变量赋值时 必须全部赋值不能部分赋值
var a, b, c, s = 3, 4, true, "str" // 自动识别
a, b, c, s := 3, 4, true, "str" // :冒号定义变量只能用于func内部 =等于号赋值 之后a只能=赋值不能:=
** 在func内部尽量不用var 用:定义变量
a := 1
// 函数外部定义变量必须用var修饰
var a = 1 // package 内 func外 定义的变量作用域在包内
func test() {
a:=2 // 此时test函数内 重新定义了局部变量a 在test内作用域优先级最高 对局部变量a的赋值并没有改变包变量a的值
}
var赋值多个变量 集合类型 一般用于赋值不同类型
var (
a1 [int可省略] = 3
s1 = "ss"
b1 = true
)
or
a1,s1,b1 := 3, "ss", true
注意编译器可自动识别类型
每个变量都有一个唯一的名字,包名是这个名字的前缀
数据类型
1.bool(1字节 和整型不能转换)
比较/逻辑表达式的结果是bool
bool默认false
2.string
3.[u]int, [u]int8, [u]int16, [u]int32, [u]int64, uintptr
不指定位则int根据系统决定位 32位系统4字节 64位系统8字节
64位操作系统, int默认是int64 32位操作系统, int默认是int32
uintptr指针 大小随操作系统
整型支持算术运算和位操作
4.byte // uint8 的别名 一般用于二进制和ascii码
5.rune // int32 的别名
go的字符型 能和数字计算 int类型可以直接变字符 字符串不能+1数字 python没有字符 '' ""都是字符串
a := 'a'
fmt.Println(reflect.TypeOf(a+1)) // 获取类型 打印int32
fmt.Printf("%c", a+1) // b
6.float32、float64
浮点数字面量会被自动类型推断为float64类型
7.complex64、complex128
复数库cmplx
欧拉公式
aa := cmplx.Pow(math.E, 1i * math.Pi) + 1
aa = cmplx.Exp(1i*math.Pi) + 1
real(v) 返回实部 image(v)返回虚部
error 接口型
go是一种强类型静态编译型语言,定义变量和常量时要显式指出数据类型,go也支持自动类型推导
定义新类型和函数时必须带上类型标识符
python import sys 其 sys.getsizeof(variable) 可以获得变量占用字节
getsizeof(1) 返回28字节 python 一切皆对象 所以占用字节多
os.path.getsize(path)
获取指定路径 path 下的文件的大小,以字节(Byte)为单位
python没有字符类型 go有rune java有char 只有静态编译语言才有字符类型 需要定义类型
go获取变量占用字节
unsafe.Sizeof(变量)
数据类型转换
一般的转换:int(),string(),byte(),[]byte()等 命名类型的转换 可用type自定义类型
go不支持变量间的隐式类型转换 var t int8 = 1 var tt int32 = t 会报错 要写var tt int8 = int(t)
对于不同的自定义类型 支持底层相同类型时转换 var t int32 = int32(tt) // tt时int64
常量到变量会进行隐式类型转换 var t int = 2.0
string()转换
string([]byte("abcd")) 会把[]byte切片转为字符串
string('a'/97) 会把字符或数字转字符串 数字当字符处理 97对应a ascii编码
strconv包:一般字符串和数字的转换用strconv包
Itoa:int转string
strconv.Itoa(int(a)) 不常用显式转换
Atoi:string转int Atoi 底层调用 ParseInt,通过ParseInt(s, 10, 0) 来实现的
strconv.Atoi(”123“) 返回123和err(成功err为nil) string()转换会变成编码
Parse类函数:Parse类函数用于转换字符串为给定类型的值:ParseBool()、ParseFloat()、ParseInt()、ParseUint()
b, err := strconv.ParseBool("true")
f, err := strconv.ParseFloat("3.1415", 64) // float64
i, err := strconv.ParseInt("-2", 10, 64) // 10进制 int64 解析"-2""
u, err := strconv.ParseUint("2", 10, 64)
func ParseInt(s string, base int, bitSize int) (i int64, err error)
func ParseUint(s string, base int, bitSize int) (uint64, error)
说明:
bitSize参数表示转换为什么位的int/uint,有效值为0、8、16、32、64。当bitSize=0的时候,表示转换为int或uint类型。例如bitSize=8表示转换后的值的类型为int8或uint8。
base参数表示以什么进制的方式去解析给定的字符串,有效值为0、2-36。当base=0的时候,表示根据string的前缀来判断以什么进制去解析:0x开头的以16进制的方式去解析,0开头的以8进制方式去解析,其它的以10进制方式解析
Format类函数:将给定类型格式化为string类型:FormatBool()、FormatFloat()、FormatInt()、FormatUint()
s := strconv.FormatBool(true)
s := strconv.FormatFloat(3.1415, 'E', -1, 64)
s := strconv.FormatInt(-42, 16) //表示将-42转换为16进制数,转换的结果为-2a。
s := strconv.FormatUint(12, 16)
第二个参数base指定将第一个参数转换为多少进制,有效值为2<=base<=36。当指定的进制位大于10的时候,超出10的数值以a-z字母表示。例如16进制时,10-15的数字分别使用a-f表示,17进制时,10-16的数值分别使用a-g表示。
FormatFloat()参数:func FormatFloat(f float64, fmt byte, prec, bitSize int) string {} 没有返回err
bitSize表示f的来源类型(32:float32、64:float64),会据此进行舍入。
fmt表示格式:'f'(-ddd.dddd)、'b'(-ddddp±ddd,指数为二进制)、'e'(-d.dddde±dd,十进制指数)、'E'(-d.ddddE±dd,十进制指数)、'g'(指数很大时用'e'格式,否则'f'格式)、'G'(指数很大时用'E'格式,否则'f'格式)。
prec控制精度(排除指数部分):对'f'、'e'、'E',它表示小数点后的数字个数;对'g'、'G',它控制总的数字个数。如果prec 为-1,则代表使用最少数量的、但又必需的数字来表示f。
字面常量量
整型字面量:
3 0600 0xBaaFacc 34324324
浮点字面量:
0. 6.33 03.30 1.e+0 1E6 3.33e-11 .123E+5
字符型字面量:
'a' '\t' '\x07' '\u12e4'
字符串字面量:
"\n" "Hello World"
强制类型转换
golang类型转换是强制的
func triangle() {
var a, b int = 3, 4
var c int
c = int(math.Sqrt(float64(a * a + b * b)))
fmt.Println(c)
}
接口强转
r.(*Type)
变量特点
变量类型在变量名后 var name int
编译器可推测变量类型 a:=1
没有char只有rune 32位
原生支持复数类型
匿名变量
python匿名变量模拟
for _, item enumerate(list1):
print(item)
匿名变量(anonymous variable)
在使用多重赋值时,如果不需要在左值中接收变量,可以使用匿名变量
匿名变量的表现是一个下画线_,使用匿名变量时,只需要在变量声明的地方使用下画线替换即可。
匿名变量不占用命名空间,不会分配内存。匿名变量与匿名变量之间也不会因为多次声明而无法使用。
在 Lua 等编程语言里,匿名变量也被叫做哑元变量。
func test() (a, b int) {
a, b = 100, 100
return
}
a, _ := test()
_, b := test()
const
python一般用大写约定或者自定义类强制不能修改;java用final不能修改
常量可以不定义类型 使用时相当于文本替换 既可以当int也可以当float 可作为各种类型使用
go的常量不大写
func consts() {
const filename string = "abc.txt"
const a, b = 3, 4
const c, d int = 3, 4 // 定义类型之后必须当int使用
math.Sqrt(a * a + b * b) // 不报错
math.Sqrt(c * c + d * d) // 报错 必须转成float64类型
}
常量可以定义在包内或函数内 其他用法相当于var
const (
a1,a2,a3=1,2,3
a4=true
)
常量组不指定类型和初始化值 该类型与上一行的类型一致
const (
x int = 11
y // int 且y的值为11
z string = "str"
t // string 且t的值为字符串str
)
常量的数据类型可以是布尔,数字,字符串 不能是结构体,函数
没有表达式的常量定义复用上一行的表达式
const (
x = iota
y // y 复用表达式 iota 则iota每行+1 此处y=1
)
常量存储在程序的只读段里 .rodata section
常量定义枚举类型
func enums() {
const(
cpp = 0
java = 1
python = 2
golang = 3
)
}
func enums1() {
const(
cpp = iota // iota关键字表示这组const是自增值 从0开始
java
python
golang
)
// 即java 1;python 2等
}
func enumsk() {
const(
b = 1 << (10 * iota) // 1024是2^10
kb
mb
gb
tb
pb
)
// 单位字节 1 1024 1048576 1073741824 1099511627776 1125899906842624
}
常量值标识符
true false
iota 用在连续的枚举类型声明中 自动增1 常量计数器 在常量组中使用
每出现一次iota则增1
分开的const语句 iota每次都从0开始
const a = iota //0
const b = iota //0
const (
a = iota // 0
b = 10 // 10
c // 10
d, e = iota, iota // iota = 3 逐行加一 所以此处d,e的iota都是3
f = iota // 4
) // iota代表的是这里的行数
nil 指针/引用型变量的默认值就是nil
接口指向一个nil结构体 则接口不是nil
指针,数组,切片,字典,通道,结构和接口
指针:
*pointer //*跟指向的类型名
数组:
[n] elementType // 数组 n长度 后跟元素类型
切片:
[] elementType
字典:
map[keyType]valueType
通道:
chan valueType
结构体:
struct {
fieldName fieldType
...
}
接口:
interface {
method1(input)(return)
...
}