Golang基础
Go语言是什么?
2009年11月10日,Go语言正式成为开源编程语言家庭的一员。
Go语言(或称Golang)是云计算时代的C语言。Go语言的诞生是为了让程序员有更高的生产效率,Go语言专门针对多处理器系统应用程序的编程进行了优化,使用Go编译的程序可以媲美C或C++代码的速度,而且更加安全、支持并行进程。
开发人员在为项目选择语言时,不得不在开发速度和性能之间做出选择。C和C++这类语言提供了很快的执行速度,而Ruby和Python这类语言则擅长快速开发。Go语言在这两者间架起了桥梁,不仅提供了高性能的语言,同时也让开发更快速。
Go语言的优势
- 可以直接编译机器码,不依赖其他库,glibc的版本有一定的要求,部署就是扔一个文件上去就完成了。
- 静态类型语言,但是有动态语言的感觉。静态语言就是可以在编译的时候检查出来隐藏的大多数问题,动态语言的感觉就是有很多包可以使用,写起来的效率很高。
- 语言层面支持并发,这个是Go最大的特色,天生的支持并发。Go就是基因里面支持的并发,可以充分的利用多核,很容易的使用并发;
- 内置runtime,支持垃圾回收,这属于动态语言的特性。目前来说的GC(内存回收机制)不算完美,但是足以应付我们所能遇到的大多数情况,特别是Go1.1之后的GC;
- 丰富的标准库,特别是网络库非常强大;
- 跨平台编译,如果Go代码不包含cgo,就可以做到Windows系统编译linux的应用。因为Go引用了plan9的代码,不依赖系统的信息;
- 内嵌C支持,Go里面也可以直接包含C代码,利用现有的丰富的C库。
GO适合用来做什么?
- 服务器编程
- 分布式系统、数据库代理器
- 网络编程
- 内存数据库
- 云平台
一. 基本类型、流程控制
1.1 第一个go程序
hello.go
package main
import "fmt"
func main(){
fmt.Println("hello go")
}
- go语言以包为管理单位,每个文件必须先声明包,程序必须有一个main包
- fmt是用于IO的包
- Println()会换行
- go语言结尾没有分号
- 一个工程只能有一个main函数
- 导入包之后必须要使用
1.2 命令行运行程序
- go run xxx.go
编译并运行xxx.go程序,并不生成xxx.exe程序
- go build xxx.go
编译xxx.go生成xxx.exe, 不运行xxx.exe
1.3 数据类型作用和命令规范
数据有类型之后,编译器就知道给该数据分配多大空间保存这个数据变量
类型 | 描述 |
uint8/uint16/uint32/uint64 | 无符号8/16/32/64位整形 |
int8/int16/int32/int64 | 有符号8/16/32/64位整形 |
float32/float64 | IEEE-754 32/64位浮点型数 |
complex64/complex128 | 32/64位实数和虚数 |
byte | 类似uint8 |
rune | 类似uint32 |
uintprt | 无符号整形,用于存放一个指针 |
1.4 变量的声明
var 变量名 变量类型
- 变量声明了,必须要使用
- 包导入了,必须要使用
- 只是声明没有初始化的变量,默认值为0
- 同一个{}作用域内,声明的变量名是唯一的
- 可以同时声明多个变量:var a, b, c int
package main
import "fmt"
func main(){
var a int
fmt.Println("The value of a: ",a)
}
得到:
1.5 变量的初始化
即声明变量的同时赋值给变量
var b int = 20
1.6 自动推导类型
:=表示自动推导,c必须为一个全新的变量(前面没有出现过的)
c := 30
package main
import "fmt"
func mul()(a,b,c int){
return 1, 2, 3
}
func main(){
var (
a = 10
b = 3.15
c = "abc"
)
fmt.Printf("a = %d, b = %f, c = %s", a, b, c)
}
声明里加()可以自动推导()里变量的类型。
1.7 Printf和Println的区别
Println是一段一段处理,自动换行
Printf是格式化输出,不能自动换行
1.8 多重初始化和匿名变量
多重初始化:a, b := 10, 20
多重初始化代码:
package main
import "fmt"
func main(){
i,j := 10,20
i,j = j,i
fmt.Printf("i = %d, j = %d\n",i,j) //i与j交换了位置
}
匿名变量_代码:
package main
import "fmt"
func mul()(a,b,c int){
return 1, 2, 3
}
func main(){
var a, b int
a, b, _ = mul()
fmt.Printf("a = %d, b = %d", a, b)
}
1.9 常量const 的使用
变量:声明用var
常量:声明用const
const a int = 10 // a被声明为int型的常量,值为10,a不允许被修改。
const b = 20 // 此处不能使用:=,直接使用=可以自动推导。
1.10 iota枚举
- iota是常量自动生成器,每隔一行,自动累加1;
- iota给常量赋值使用,重置为0
- 如果是同一行,值都一样
package main
import "fmt"
func main(){
const(
a = iota
b = iota
c = iota
)
fmt.Printf("a = %d, b = %d, c = %d\n",a,b,c)
const d = iota
fmt.Printf("d = %d\n",d)
}
1.11 基础数据类型
类型 | 名称 | 长度 | 初始默认值 |
bool | 布尔类型 | 1字节 | false |
byte | 字节型 | 1字节 | 0 |
rune | 字符类型 | 4字节 | 0 |
int,uint | 整型 | 4或8 | 0 |
int8,uint8 | 整型 | 1字节 | 0 |
int16,uint16 | 整型 | 2字节 | 0 |
int32,uint32 | 整型 | 4字节 | 0 |
int64,uint64 | 整型 | 8字节 | 0 |
float32 | 浮点型 | 4字节 | 0.0 |
float64 | 浮点型 | 8字节 | 0.0 |
complex64 | 复数类型 | 8字节 | |
complex128 | 复数类型 | 16字节 | |
uintptr | 整型 | 4字节/8字节 | 足以存储指针的uint32或uint64整数 |
string | 字符串 | "" |
1.12 fmt包的格式化输出输入
格式 | 含义 |
%% | 一个%字面量 |
%b | 一个二进制整数值(基数为2) |
%c | 字符型 |
%d | 整数型 |
%f | 标准计数法表示的浮点数 |
%o | 一个八进制表示的数字 |
%p | 十六进制 |
1.13 变量的输入
package main
import "fmt"
func main(){
var a int
fmt.Printf("请输入变量a: ")
// fmt.Scanf("%d",&a)
fmt.Scan(&a)
fmt.Printf("a = %d ",a)
}
1.14 range的使用
package main
import "fmt"
func main(){
str := "abc"
for i,data := range str{
fmt.Printf("str[%d] = %c\n",i,data)
}
}
1.15 goto的使用
二. 函数、工程管理
2.1 函数
2.1.1 无参无返回值函数的定义
package main
import "fmt"
func MyFunc(){
a := 666
fmt.Println("a = ", a)
} // MyFunc()函数也可以放在main函数后面
func main(){
MyFunc()
}
2.1.2 有参无返回值函数:普通参数列表
package main
import "fmt"
//定义函数时,在函数名后面()定义的参数叫形参
func MyFunc(a int){
a = 111
fmt.Println("a = ",a)
}
func main(){
//调用函数传递的参数叫做实参
MyFunc(5)
MyFunc2(10,20)
}
func MyFunc2(a int, b int){
fmt.Println("a = ", a, " b = ",b)
}
2.1.3 不定参数类型
package main
import "fmt"
// “...int”类型的参数,表示不定参数,可以传0或多个参数
func MyFunc(args ...int){
fmt.Println("len(args) = ", len(args))
for i:=0; i < len(args); i++{
fmt.Printf("args[%d] = %d\n",i,args[i])
}
for i, data := range args{
fmt.Printf("i = %d, data = %d\n",i,data)
}
}
func main(){
MyFunc(1)
MyFunc(1,2,3)
}
2.1.4 不定参数的传递
package main
import "fmt"
func myfunc1(temp ...int){
for _, data := range temp{
fmt.Println("data = ", data)
}
}
func myfunc2(temp ...int){
for _, data := range temp{
fmt.Println("data = ", data)
}
}
func test(args ...int){
//全部元素传给myfunc1
myfunc1(args...)
//传0号和1号元素给myfunc2
myfunc2(args[:2]...)
}
func main(){
test(1,2,3,4,5)
}
/*运行结果
PS C:\Users\gtc\Desktop\Go\Go_demo> go run .\main.go
data = 1
data = 2
data = 3
data = 4
data = 5
data = 1
data = 2
*/
2.1.5 函数只有一个返回值
package main
import "fmt"
func myfunc() int {
return 100
}
func main(){
a := myfunc()
fmt.Println(a)
}
2.1.6 函数有多个返回值
package main
import "fmt"
func myfunc01()(int , int , int){
return 1, 2, 3
}
//go官方推荐写法
func myfunc02()(a int , b int , c int){
a = 100
b = 200
c = 300
return
}
func main(){
a, b, c := myfunc02()
fmt.Printf("a = %d, b = %d, c = %d\n",a,b,c)
}
2.1.7 有参有返回值函数的使用
package main
import "fmt"
func MinAndMax(num1 int, num2 int)(min int, max int){
if num1 > num2{
min = num2
max = num1
}else{
min = num1
max = num2
}
return
}
func main(){
min, max := MinAndMax(10,20)
fmt.Printf("min = %d, max = %d\n",min,max)
}
三. 复合类型
四. 面向对象编程
五. 异常、文本文件处理