[TOC]
# 定义
声明格式,声明了就一定要使用
~~~
var 变量名 类型
~~~
# 多个值定义
~~~
package main
import "fmt"
func main() {
//声明了就一定要使用
var a int
fmt.Println("a = ", a)
//可以同时声明多个
//var b, c int
//自动推导.必须初始化,通过初始化值确定类型
c := 30
fmt.Println("c = ", c)
//%T打印所属类型,prinf
fmt.Printf("c type is %T", c)
}
~~~
# iota枚举
iota常量自动生成器,每个一行,自动累加1,给常量赋值使用
iota遇到const,重置为0
~~~
func main() {
//1. iota常量自动生成器,每个一行,自动累加1
//2. iota给常量赋值使用
const (
a = iota //0
b = iota
c = iota
)
fmt.Printf("a = %d, b = %d, c = %d\n", a, b, c)
//3. iota遇到const,重置为0
const d = iota
fmt.Printf("d = %d\n", d)
//4. 可以只写一个iota
const (
a1 = iota
b1
c1
)
fmt.Printf("a1 = %d, b1 = %d, c1 = %d\n", a1, b1, c1)
//5. 如果是同一行,值都一样
const (
i = iota
j1, j2, j3 = iota, iota, iota
k = iota
)
fmt.Printf("i = %d, j1 = %d, j2 = %d, j3 = %d, k = %d\n", i, j1, j2, j3, k)
}
~~~
输出
~~~
a = 0, b = 1, c = 2
d = 0
a1 = 0, b1 = 1, c1 = 2
i = 0, j1 = 1, j2 = 1, j3 = 1, k = 2
~~~
# fmt包的格式化输出和输入
![](https://box.kancloud.cn/87537def8972cd8c6d1c5702485d40d5_849x615.png)
![](https://box.kancloud.cn/1700074f4101f81e9f8715f9ca814ba9_846x443.png)
~~~
%v 相应值的默认格式。在打印结构体时,“加号”标记(%+v)会添加字段名
%#v 相应值的 Go 语法表示
%T 相应值的类型的 Go 语法表示
%% 字面上的百分号,并非值的占位符
~~~
~~~
func main() {
a := 10
b := "abc"
c := 'a'
d := 3.14
//格式化输出类型
fmt.Printf("a = %d, b = %s, c = %c, d = %f\n", a, b, c, d)
//%v自动匹配格式输出,字符变为ASCII码了,浮点数0没了
fmt.Printf("a = %v, b = %v, c = %v, d = %v\n", a, b, c, d)
}
~~~
输出
~~~
a = 10, b = abc, c = a, d = 3.140000
a = 10, b = abc, c = 97, d = 3.14
~~~
# 打印地址
~~~
func main() {
var a int = 1
fmt.Println(&a)
}
~~~
# 变量的输入
scan获取用户输入,记住要用取地址符
~~~
func main() {
var a int
fmt.Printf("请输入变量a: ")
//阻塞用户等待输入
//fmt.Scanf("%d", &a) //别忘了&
fmt.Scan(&a)
fmt.Println("a = ", a)
}
~~~
获取多个值用空格隔开
~~~
import "fmt"
func main() {
var a int
var b string
fmt.Scanf("%d%s", &a, &b)
fmt.Println(a)
fmt.Printf(b)
}
~~~
输出
~~~
11 222
11
222
~~~
# 类型
byte字节, rune字符
## 基础类型
go语言内置以下这些基础类型
![](https://box.kancloud.cn/652dddb5095bd670469cd8285b6f69d5_858x669.png)
### 字符串
**字符串长度**
~~~
func main() {
str1 := "mike"
fmt.Println("len(str1) = ", len(str1))
}
~~~
**取字符串某个部位**
~~~
func main() {
str1 := "mike"
fmt.Printf("str1[0] = %c", str1[0])
}
~~~
### 字符转为ASCII
~~~
func main() {
ch := 'a'
fmt.Println("ch = ", ch)
}
~~~
输出
~~~
ch = 97
~~~
### 字符串两种表示方式
双引号"",可以包含控制知乎
反引号``,原样输出,空格和换行都有
### 复数类型
判断类型和输出实部和虚部
~~~
func main() {
var t complex128
t = 2.1 + 3.14i
fmt.Println("t = ", t)
//自动推到类型
t2 := 3.3 + 4.4i
fmt.Printf("t2 type is %T\n", t2)
//通过内建函数,取实部和虚部
fmt.Println("实部 = ", real(t2), " , 虚部 = ", imag(t2))
}
~~~
输出
~~~
t = (2.1+3.14i)
t2 type is complex128
实部 = 3.3 , 虚部 = 4.4
~~~
### 整数和浮点型
int和平台相关,不同平台不一样
![](https://box.kancloud.cn/cd6c2fece28bd8f0a0c9ed984f097326_1074x471.png)
# 类型别名
给类型起别名
~~~
func main() {
//给int64起个别名叫bigint
type bigint int64
var a bigint //等价于var a int64
fmt.Printf("a type is %T\n", a)
type (
long int64
char byte
)
var b long = 11
var ch char = 'a'
fmt.Printf("b = %d, ch = %c\n", b, ch)
}
~~~
输出
~~~
a type is main.bigint
b = 11, ch = a
~~~
## 非本地类型不能定义方法
能够随意地为各种类型起名字,是否意味着可以在自己包里为这些类型任意添加方法?参见下面的
~~~
package main
import (
"time"
)
// 定义time.Duration的别名为MyDuration
type MyDuration = time.Duration
// 为MyDuration添加一个函数
func (m MyDuration) EasySet(a string) {
}
func main() {
}
~~~
代码说明如下:
* 第 8 行,使用类型别名为 time.Duration 设定一个别名叫 MyDuration。
* 第 11 行,为这个别名添加一个方法。
编译上面代码报错,信息如下:
~~~
cannot define new methods on non-local type time.Duration
~~~
编译器提示:不能在一个非本地的类型 time.Duration 上定义新方法。非本地方法指的就是使用 time.Duration 的代码所在的包,也就是 main 包。因为 time.Duration 是在 time 包中定义的,在 main 包中使用。time.Duration 包与 main 包不在同一个包中,因此不能为不在一个包中的类型定义方法。
解决这个问题有下面两种方法:
* 将第 8 行修改为 type MyDuration time.Duration,也就是将 MyDuration 从别名改为类型。
* 将 MyDuration 的别名定义放在 time 包中。
# 常量
iota在一个作用域里面是递增的,出了就重新开始了
常量使用const修饰,代表永远是只读的,不能修改
语法:
type可以省略
~~~
const identifier [type] = value
~~~
~~~~
const b string = "123"
const b = "123"
~~~
其他写法
~~~
const (
a = 1
b = 2
c //什么都不写就和前面值是一样是2
)
~~~
- 基础
- 简介
- 主要特征
- 变量和常量
- 编码转换
- 数组
- byte与rune
- big
- sort接口
- 和mysql类型对应
- 函数
- 闭包
- 工作区
- 复合类型
- 指针
- 切片
- map
- 结构体
- sync.Map
- 随机数
- 面向对象
- 匿名组合
- 方法
- 接口
- 权限
- 类型查询
- 异常处理
- error
- panic
- recover
- 自定义错误
- 字符串处理
- 正则表达式
- json
- 文件操作
- os
- 文件读写
- 目录
- bufio
- ioutil
- gob
- 栈帧的内存布局
- shell
- 时间处理
- time详情
- time使用
- new和make的区别
- container
- list
- heap
- ring
- 测试
- 单元测试
- Mock依赖
- delve
- 命令
- TestMain
- path和filepath包
- log日志
- 反射
- 详解
- plugin包
- 信号
- goto
- 协程
- 简介
- 创建
- 协程退出
- runtime
- channel
- select
- 死锁
- 互斥锁
- 读写锁
- 条件变量
- 嵌套
- 计算单个协程占用内存
- 执行规则
- 原子操作
- WaitGroup
- 定时器
- 对象池
- sync.once
- 网络编程
- 分层模型
- socket
- tcp
- udp
- 服务端
- 客户端
- 并发服务器
- Http
- 简介
- http服务器
- http客户端
- 爬虫
- 平滑重启
- context
- httptest
- 优雅中止
- web服务平滑重启
- beego
- 安装
- 路由器
- orm
- 单表增删改查
- 多级表
- orm使用
- 高级查询
- 关系查询
- SQL查询
- 元数据二次定义
- 控制器
- 参数解析
- 过滤器
- 数据输出
- 表单数据验证
- 错误处理
- 日志
- 模块
- cache
- task
- 调试模块
- config
- 部署
- 一些包
- gjson
- goredis
- collection
- sjson
- redigo
- aliyunoss
- 密码
- 对称加密
- 非对称加密
- 单向散列函数
- 消息认证
- 数字签名
- mysql优化
- 常见错误
- go run的错误
- 新手常见错误
- 中级错误
- 高级错误
- 常用工具
- 协程-泄露
- go env
- gometalinter代码检查
- go build
- go clean
- go test
- 包管理器
- go mod
- gopm
- go fmt
- pprof
- 提高编译
- go get
- 代理
- 其他的知识
- go内存对齐
- 细节总结
- nginx路由匹配
- 一些博客
- redis为什么快
- cpu高速缓存
- 常用命令
- Go 永久阻塞的方法
- 常用技巧
- 密码加密解密
- for 循环迭代变量
- 备注
- 垃圾回收
- 协程和纤程
- tar-gz
- 红包算法
- 解决golang.org/x 下载失败
- 逃逸分析
- docker
- 镜像
- 容器
- 数据卷
- 网络管理
- 网络模式
- dockerfile
- docker-composer
- 微服务
- protoBuf
- GRPC
- tls
- consul
- micro
- crontab
- shell调用
- gorhill/cronexpr
- raft
- go操作etcd
- mongodb