初始Go语言
2009年11月10日正式发布。
Go语言(Golong)是云计算时代的C语言。
特点:高性能 + 开发快捷
Go语言优势
- 不需要其他库
- 静态型语言,但有动态语言感觉
- 语言层面支持并发
- 内置runtime,支持垃圾回收 GC
- 简单易学
- 丰富的标准库
- 跨平台编译
- 内置C支持
适合用来做什么
- 服务器编程
- 分布式系统
- 网络编程
- 内存数据库
- 云平台
推荐环境
- LiteIDE
- Sublime Text
学习资料
- Go语言官网 https://golang.google.cn/
- Go中文社区 https://studygolang.com/
- Go中文在线文档 http://docscn.studygolang.com/doc/
编码思路
把程序当做一个商场:
- 入口:go有且只有一个入口:main函数
使用图形界面编译时,一个工程(文件夹)只能有一个main函数,否则会编译冲突;
解决办法:1.新建文件夹 2.命令行运行
常用命令:
go build xxx.go 生成一个可执行文件
go run xxx.go 不生成程序,直接运行
- 工作:调用函数
一些常识
- 函数左括号必须和函数名在同一行,不能换行
- Println() 会自动换行
- 调用函数,大部分都需要导入包
- go语言以包作为管理单位
- 每个文件必须先声明包 package
- 程序必须有一个main包(重要)
- 导入包后必须要使用,不使用会报错
- // /※ ※/ 两种注释方式
- go语言结尾没有分号
命名
- 命名规范:字母,下划线,数字
- 不能以数字开头
- 名字不能是关键字
- 区分大小写
变量
定义
变量:程序运行期间,可以改变的量
- 变量声明: var 变量名 类型
- 变量初始化:声明变量时,同时赋值 var x int = 100
示例:
var a // 变量声明
a=10 // 变量赋值
var b int // 初始化(声明变量时,同时赋值)
- 自动推导类型,必须初始化,因为是通过初始化的值来确定类型(常用)
示例:
c := 30
ftm.Printf("c type is %T\n" , c) // %T打印变量所属的类型
- 多重赋值
a, b := 10, 20
// 交换两个变量的值可以这么写:
i, j := 10, 20
i, j = j, i
- 匿名变量
匿名变量配合函数返回值使用是才有优势,常用于丢弃一些不需要的返回值
tmp , _ = i , j // tmp为i的值,下划线被丢弃
特性
- 变量声明了,必须要使用
- 只是声明,没有初始化的变量,默认值为0
- 同一个大括号{}里,声明的变量名是唯一的
- 可以同时声明多个变量
- 变量的赋值是可以改变的
- 赋值前必须先声明变量,使用自动推导类型时,可以不显示声明类型;因为 := 自动推导的类型的作用就是先声明变量,然后给变量进行赋值
- 对同一个变量只能使用一次自动推导类型,因为第一次定义时,已自动声明,再次声明会导致重复错误。赋值可以使用n次。
Println() 和 Printf() 的区别
fmt.Println("a = ", a ) // 按逗号区分一段一段处理,自动加换行符
fmt.Println("a = ", a , ", b = ", b , " , c = ", c)
fmt.Printf("a = %d\n" , a ) // 格式化输出,把a的内容放在%d的位置;\n代表换行符
fmt.Printf("a = %d, b = %d, c= %d\n", a , b , c ) // 多个变量时控制格式更加简单
常量
定义
常量:程序运行期间,不可以改变的量;不允许修改
- 常量声明:const a int = 10
特性
- 常量也可自动推导,不使用 := ,直接使用 = ;
示例:
const b = 10
多个变量或常量定义
不同类型变量的声明(定义)
示例:
传统写法:
var a int
var b float64
a, b = 10, 3.14
简洁写法:
var (
a int
b floaf64
)
常量声明
示例:
传统写法:
const i int = 10
const j float = 3.14
简洁写法:
const (
i int = 10
j float64 = 3.14
)
也可以自动推导类型
const (
i = 10
j = 3.14
)
iota枚举(适用常量)
定义
- iota是一个常量自动生成器,每隔一行自动累加1
- iota是给常量赋值使用的
- iota遇到const,会重置为0
示例:
const (
a = iota // 0
b = iota // 1
c = iota // 2
)
const d = iota // 0
- 也可以只写一个iota
const (
a1 = iota //0
b1 // 1
c1 // 2
)
- 如果是同一行,值都一样
const (
i = iota // 0
j1, j2, j3 = iota, iota, iota // 1, 1, 1
k = iota // 2
)
数据类型
计算机是用来做计算的,计算前需要先存放数据,如何存数?
- 作用:告诉编译器,数据应该以多大的内存存储
- 类型:同一类数据
分类
Go语言内置一下基础类型
类型 ++++++ 名称 ++++++ 长度 ++++++ 零值 ++++++ 说明
bool - 布尔类型 - 1 - false - 其值不为真即为假,不可以用数字代表true或false
byte - 字节型(单字符类型) - 1 - 0 - uint8别名
rune - 字符类型 - 4 - 0 - 专用于存储unicode编码,等价于uint32
int,uint - 整型 - 4或8 - 0 - 32位或64位
int8, uint8 - 整型 - 1 - 0 - -128~127,0~255
int16, uint16 - 整型 - 2 - 0 - -32768~32767 , 0~65535
int32, uint32 - 整型 - 4 - 0 - -21亿~21亿,0~42亿
int64, uint64 - 整型 - 8 - 0
float32 - 浮点型 - 4 - 0.0 - 小数位精确到7位
float64 - 浮点型 - 8 - 0.0 - 小数位精确到15位
complex64 - 复数类型 - 8
complex128 - 复数类型 - 16
uintptr - 整型 - 4或8 - 足以存储指针的uint32或uint64整数
string - 字符串 - - “” - utf-8 字符串
bool类型
- 声明变量
var a bool // 没有初始化时,初始值为false
- 变量赋值 a = true
- 自动推导类型 var b = false 或 c := false
浮点型
- 声明变量
var f1 float32
f1 = 3.14
- 自动推导类型(默认推导类型float64)
f1 := 3.14
- float64存储小数比float32更精确
字符类型
- 计算机不可直接存字符,通过ascii码来对应字符;97 =》 'a'
var ch byte
ch = 97
// 格式化输出,%c以字符型方式打印,%d以整型方式打印
fmt.Printf("%c, %d\n", ch, ch)
// 字母大小写相差32,小写比大写大,大小写之间可以通过加减进行转换
// 以'\'反斜杠开头的字符是转义字符
字符串类型
- 声明变量(双引号)
var str1 string
str1 = "abc"
- 自动推导类型
ter2 := "mike"
- 内建函数,len()可以测字符串的长度,有多少个字符
len(str2)
字符和字符串的区别
字符:
- 单引号
- 元素往往都只有一个字符,转义字符除外
字符串:
- 双引号
- 字符串有1个或多个字符组成
- 字符串都是隐藏了一个结束符,'0'
str = "a" //由'a'和'\0'组成了一个字符串
// 访问字符串内单个字符:
str = "hello go" // 只想操作字符串的某个字符,从0开始操作
str[0] // 访问 'h'
复数类型
- 声明变量
var t complex128
t = 2.1 + 3.14i
- 自动推导类型
t2 := 3.3 + 4.4i
- 通过内建函数取实部和虚部
real(t2) // 实部3.3
imag(t2) // 虚部4.4
fmtb包的格式化输入输出
输出格式化
- %T 打印操作变量所属类型
- %d 整型格式
- %s 字符串格式
- %c 字符格式
- %f 浮点型格式
- %v 自动匹配格式
- %t 布尔类型
输入格式化
- %d 阻塞等待用户的输入;fmp.Scan(&a) 也可以同样的效果
类型转换
- 不是什么类型都能转的,需要可以兼容的才行
- bool类型不能转化为整型,整型也可能转化为布尔;这种不能转化的类型,就叫做不兼容类型。
- 字符型本质上就是整型,可以强制类型转化;把ch的值取出来后,转成int,再给t赋值
var ch byte
ch = 'a'
var t int
t = int(ch)
类型别名(重要)
定义:给一个类型起个别名
示例:
type bigint int64 // 给int64起一个别名叫bigint
bigint a // 等价于 int64 a
// 多个别名同时定义
type (
long int64
char byte
)
运算符
算术运算符
- +
- -
- 乘
- /
- %
- ++
- --
关系运算符
- <
- ==
- !=
- <=
=
逻辑运算符
- &&
- ||
- !
- 非0就是真,0为假(但是go语言的bool类型和整型不兼容)
- 逻辑运算符的结果为bool类型,所以可以和整型搭配来用
位运算符
- & 按位与
- | 按位或
- ^ 异或
- << 左移
- 》 右移
赋值运算符
- =
- +=
- -=
- 乘等
- %= 求余后再赋值
- <<= 左移后再赋值
- 》= 右移后再赋值
- &= 按位与后赋值
- ^= 按位异或后再赋值
- |= 按位或后再赋值
其他运算符
- & 取地址运算符 - &a 变量a的地址
- ※ 取值运算符 - 指针变量a所指向内存的值
运算符优先级
- 7 =》^ 、!
- 6=》※、/、%、<<、>>、&、&^
- 5=》+、-、|、^
- 4=》==、!=、<、<=、>=、>
- 3=》<
- 2=》&&
- 1=》||
流程控制
Go支持三种程序运行结构:顺序结构、选择结构、循环结构
- 顺序结构:程序按顺序执行,不发生跳转
- 选择结构:依据是否满足条件,有选择的执行相应功能
- 循环结构:依据条件是否满足,循环多次执行某段代码
选择结构
if语句
- if和{就是条件,没有小括号,条件通常都是关系运算符
- 左括号{和if是在同一行
if s == "王思聪" {
fmt.Println("111")
}
- if支持一个初始化语句,初始化语句和判断条件以分号分隔
if a := 10; a==10{ // 条件为真,执行大括号内内容
fmt.Println("111")
}
- 多分支 if elseif else
a:=10
if a == 10{
fmt.Println("a=10")
}else if a>10{
fmt.Println("a>10")
}else if a<10{
fmt.Println("a<10")
}else{
fmt.Println("这是不可能的")
}
switch 语句
可以认为是if else 的另一种写法
- switch 后面是变量本身,无括号
- 默认保函break,不写也可以
- 增加关键字fallthrough ,相当于去掉默认的break,不跳出循环,后面的无条件执行
- 可以一个case多个条件
switch num{
case 1:
fmp.Println("按下的是1楼")
case 2:
fmp.Println("按下的是2楼")
case 3:
fmp.Println("按下的是3楼")
case 4,5,6:
fmp.Println("按下的是yyy楼")
default:
fmp.Println("按下的是xxx楼")
}
- 支持一个初始化语句,初始化语句和变量本身以分号分隔
- 可以没有条件,也可以再case后放条件
score := 85
switch {
case score>90:
fmp.Println("优秀")
case score>80:
fmp.Println("良好")
case score>70:
fmp.Println("一般")
default:
fmp.Println("其他")
}
循环结构
- 只有for,没有while和do while
for的使用
- 格式
for 初始化条件; 判断条件; 条件变化{
}
for i:=1 ; i<=100; i++{
sum = sum+i
}
range的使用(迭代)
配合数组和切片使用。
迭代打印每个元素,默认返回两个值:一个是元素的位置,一个是元素本身
str := "abc"
// 通过for打印每一个字符
for i := 0; i<len(str); i++{
fmt.Printf("str[%d]=%c\n",i,str[i])
}
// 迭代打印每个元素,默认返回两个值:一个是元素的位置,一个是元素本身
for i, data := range str{
fmt.Printf("str[%d]=%c",i,data)
}
// 也可以这么写,第二个返回值默认丢弃,返回元素的位置(下标)
for i := range str{ // 等价于 for i , _ := range str{
fmt.Printf("str[%d]=%c",i,str[i])
}
跳转结构
break和continue的区别
break可用于for、switch、select,而continue仅能用于for循环
i := 0
for{ // for后面不写任何东西,应用为真,死循环
if i==5 {
// break // 跳出循环;如果多层循环,跳出最近的
// contonue // 跳出本次循环
}
}
goto的使用
goto可以用在任何地方,但是不能跨函数使用
fmt.Println("111111111")
goto End // goto是关键字,End是用户起的名字,叫做标签
fmt.Println("222222222")
End:
fmt.Println("3333333")