go的变量、关键字、常量与枚举、一点点基础知识补充
与其说是教程,更像是总结
一起学习
1. 变量的定义
go语言的变量定义与其他语言(c,cpp,java…)不太一样,这个需要适应一下。
下面主要以一个个小实列来解释说明,不会是全部说明,也做不到全部说明(全部说明那叫官方文档)
这里创建一个文件夹test(名称随意),
在文件夹中创建一个文件main.go(名称随意)
1.1 自定义和使用Var关键字
单变量定义
package main
import "fmt"
func variableZeroValue() {
//像数据库的变量定义
var a int //默认为0
var s string
//空串会输出类似一个空格
fmt.Println(a, s, a)
fmt.Println(a, a)
//%s会输出内容,%q会输出引号包裹内容
fmt.Printf("%d,%q,%s\n", a, s, s)
s = "hello"
fmt.Printf("%d,%q,%s\n", a, s, s)
}
func main() {
variableZeroValue()
}
运行程序
1.打开终端 Ctrl+Shift+`
2.在终端中输入下面指令, 其中main(是你自己设置的文件名称)
go run main.go
3.查看输出结果展示
下面都不在重复如何运行程序啦
继续继续
多变量定义
func variableInitialValue() {
//像数据库的多变量定义
var a, b int = 3, 4
var s string = "abc"
//空串会输出类似一个空格
fmt.Println(a, s, b)
fmt.Println(a, b)
//%s输出内容,%q会输出引号包裹内容
fmt.Printf("%d,%q,%s\n", a, s, s)
}
运行结果:
PS F:\Desktop\test> go run main.go
3 abc 4
3 4
3,"abc",abc
全局变量定义
在go语言的规则中,只有var能定义全局的变量,为什么是”只有”,因为后面还有其他便捷的定义方式。
还有,不知道你发现了go语言的严格没有,go的变量定义了必须使用,不然就给你报错,编译都过不了,还有一点你可能没发现,那就是变量名称的大小写,这个以后会说明的(挖点坑)。
下面是定义全局变量
package main
import "fmt"
var aa = 3
var bb = 4
var (
cc = 3
dd = 3
ee = "hello"
)
func main() {
fmt.Println(aa, bb, cc, dd, ee)
}
PS F:\Desktop\test> go run main.go
3 4 3 3 hello
嘿嘿,不知道你发现上面的例子没写具体类型了没有,接着往后看看
让编译器自动觉定类型
弱类型定义数据
那强类型是啥?
强类型就是var a int = 3 ,我直接告诉它我就要int型,这种定义方式就是强类型,下面是弱类型的案例代码:
func variableTypeDedution() {
//弱类型定义数据
var a, b, c, d = 3, 4, true, "abc"
fmt.Println(a, b, c, d)
}
冒号赋值
这个定义变量时就方便很多了,那也许你会好奇,第一,那我怎么知道它自动转换成了啥类型呢?第二,我不想要他的类型怎么办?
下面案例会给出答案
func variableShorter() {
//冒号赋值
a, b, c, d := 3, 4, true, "abc"
b = 5
fmt.Println(a, b, c, d)
//输出变量的类型,解决第一个问题
fmt.Printf("b type:%T\n", b)
fmt.Printf("c type:%T\n", c)
fmt.Printf("d type:%T\n", d)
//强制类型转换,解决第二个问题
b = (float)b
fmt.Printf("b type:%T\n", int64(b))
}
运行上面两个函数的结果:
PS F:\Desktop\test> go run main.go
3 4 true abc
3 5 true abc
b type:int
c type:bool
d type:string
b type:int64
1.2 需要注意的细节
默认值
整型和浮点型变量默认值:0
字符串默认是空串
布尔值默认是false
函数、指针变量、切片默认值为nil(后面会讲的)
特殊值
int unit uintptr 大小取决于平台
别名
后面讲的
byte == UTF-8单字节 uint8别名
rune == unicode 4字节 int32别名
通用打印输出
常用打印
- %v 只输出所有的值
- %+v 先输出字段类型,再输出该字段的值
- %#v 先输出结构体名字值,再输出结构体(字段类型+字段的值)
- %T 输出变量的类型
整型打印
%5d , 123 = [ 123]
%05d , 123 = [00123]
字符串打印
%s,”hello” = [hello]
%q,”hello” = [“hello”] 会带双引号括起来
2. go的25个保留关键字
go和其他语言不太相同,它只有25个关键字,如下:
包管理(2个):
import package
程序实体声明与定义(8个):
chan const func interface map struct type var
程序流程控制(15个):
break case continue default defer else fallthrough
for go goto if range return select switch
这些关键字大部分都是常用的,后面也都会使用到,这里推荐一篇讲的比较全的一篇文章
3. go语言的基本数据类型
Go语言的基本类型有:
注意,没有char类型
- bool
- string
- int、int8、int16、int32、int64
- uint、uint8、uint16、uint32、uint64、uintptr
- byte // uint8 的别名
- rune // int32 的别名 代表一个 Unicode 码
- float32、float64
- complex64、complex128
说明一下complex64
这个一般用不到的,了解一下:
complex64 = 实部(float32) + 虚部(float32) complex128 = 实部(float64) + 虚部(float64)
上面所列举的都开始不需要就全部掌握,了解几个常用的就可以,后面会慢慢使用到的
4. 总结小案例
那来验证一下伟大的欧拉公式,再强调一下啊,是验证不是证明。
下面是从百度百科复制来的定义
package main
import (
"fmt"
"math"
"math/cmplx"
)
func eular() {
/*
原始的定义方式
var x complex128 = complex(1, 2) // 1+2i
var y complex128 = complex(3, 4) // 3+4i
*/
//偷懒
c := 3 + 4i
//求模,也就是求绝对值(不准确,方便理解)
println(cmplx.Abs(c)) //+5.000000e+000
//证明欧拉公式,1i就是虚数的i
println(cmplx.Pow(math.E, 1i*math.Pi) + 1)
//(0.000+0.000i)
fmt.Printf("%.3f\n", cmplx.Exp(1i*math.Pi)+1)
}
func main() {
eular()
}
输出结果:
PS F:\Desktop\test> go run main.go
+5.000000e+000
(+0.000000e+000+1.224647e-016i)
(0.000+0.000i)
验证通过
5. 常量与枚举
5.1 常量
go语言中常量一般不会大写(对比其他语言来说的),因为大小写在go语言中有其他的含义(后面会说)
下面是常量的使用:
//定义在函数外
const c = 5
func consts() {
//定义在函数内
const (
fileName = "abc.txt"
a, b = 3, 4
)
var c int
//const的本质就是固定的文本,所以编译器可以帮忙处理类型转换
c = int(math.Sqrt(a*a + b*b))
fmt.Println("c= ", c, fileName)
}
5.2 枚举
直接上代码案例,核心是对iota的理解,可以理解为一颗种子,它在枚举中的用法比较丰富
package main
import (
"fmt"
)
func enums() {
//普通枚举定义
const (
z = 0
x = 1
c = 2
v = 3
)
const (
//iota表示自增值种子(从0开始)
// _ 跳值
cpp = iota
java
python
_
goland
)
//iota位掩码表达式
const (
IgEggs = 1 << iota // 1 << 0 which is 00000001
IgChocolate // 1 << 1 which is 00000010
IgNuts // 1 << 2 which is 00000100
IgStrawberries // 1 << 3 which is 00001000
IgShellfish // 1 << 4 which is 00010000
)
//iota定义数量级
const (
b = 1 << (10 * iota)
kb
mb
gb
tb
pb
)
fmt.Println(z, x, c, v)
fmt.Println(cpp, goland, python, java)
fmt.Println(IgEggs, IgChocolate, IgNuts, IgStrawberries, IgShellfish)
fmt.Println(b, kb, mb, gb, tb, pb)
}
func main() {
enums()
}
输出结果:
PS F:\Desktop\test> go run main.go
0 1 2 3
0 4 2 1
1 2 4 8 16
1 1024 1048576 1073741824 1099511627776 1125899906842624
5.3 需要注意的细节
注意,go语言的枚举不想其他语言,不使用itoa只有const就是在定义普通的变量,只是长得向枚举类型,使用itoa后才有枚举效果(个人的简单理解)
枚举 const
const(
a = 0
b = 1
c = 2
)
a,b,c -> 0,1,2
const(
a = 10
b
c
)
a,b,c -> 10,10,10
种子 iota(自增器)
const(
a = itoa
b = itoa
c = itoa
)
a,b,c -> 0,1,2
const(
a = itoa
b
c
)
a,b,c -> 0,1,2
6. 基础知识补充
6.1 常见运算符
A = 0011 1100 【60】
B = 0000 1101 【13】
A&B = 0000 1100 同1为1
A|B = 0011 1101 遇1为1
A^B = 0011 0001 不同为1
<< 左移
A << n == A * 2^n
A << 2 == A * 4 == 60 * 4 == 240 == 1111 0000
>> 右移
A >> n == A / 2^n
A >> 2 == A / 4 == 60 / 4 == 15 == 0000 1111
6.2 二进制运算符
//测试输出
var n int
//输出一个整数的二进制
for i := 0; i < int(unsafe.Sizeof(n)); i++ {
fmt.Print(60 >> i & 1)
}
//输出一个整数的二进制
fmt.Printf("\n%b", 60)
结果输出:
PS F:\Desktop\test> go run main.go
00111100
111100