golang
特色
- 简单、快速、安全
- 并行、有趣、开源
- 内存管理、v数组安全、编译迅速
高性能分布式系统开发、海量并行处理、游戏服务端开发再好不过了
一个go程序
package main
import "fmt"
func main() {
fmt.println("hello world!")
}
$ go run main.go
hello world!
基础组成
- 包声明
package - 引入包
import - 函数
func - 变量
var - 语句 & 表达式
- 注释 不会被编译
//单行注释/* */多行注释
标识符
标识符用来命名变量、类型等程序体。一个或者多个字母[a-zA-Z]、数字[0-9]、下划线_组成,
但是第一个字符必须为_或者字母
-
有效
- hello、krc、j、_a、a123、retVal
-
无效
- 1abc (首字母不能为数字)、case (关键词)、a+b (出现非约束字符)
关键词
| 类型 | 类型 | 类型 | 类型 | 类型 |
|---|---|---|---|---|
| break | default | func | interface | select |
| case | defer | go | map | struct |
| chan | else | goto | package | switch |
| const | fallthrough | if | range | type |
| continue | for | import | return | var |
预定义
| 类型 | 类型 | 类型 | 类型 | 类型 | 类型 | 类型 | 类型 | 类型 |
|---|---|---|---|---|---|---|---|---|
| append | bool | byte | cap | close | complex | complex64 | complex128 | uint16 |
| copy | false | float32 | float64 | imag | int | int8 | int16 | uint32 |
| int32 | int64 | iota | len | make | new | nil | panic | uint64 |
| println | real | recover | string | true | uint | uint8 | uintptr |
golang中数据类型
- 布尔类型 true or false
var b bool = true
var c bool = false
- 数字类型
整型 int、浮点型 float32、float64,原生支持复数,其中位的运算采用补码
| 类型 | 类型 | 类型 | 类型 |
|---|---|---|---|
| uint8 | uint16 | uint32 | uint64 |
| int8 | int16 | int32 | int64 |
| float32 | float64 | complex64 | complex128 |
| byte | rune | uint | int |
| uintptr |
- 字符串类型
使用utf-8编码标识unicode文本
-
派生类型
- 指针类型 Pointer
- 数组类型
- 结构化类型 struct
- Channel类型
- 函数类型
- 切片类型
- 接口类型 interface
- Map 类型
var a = "世界你好"
var b string = "hello world"
var c bool
不带声明的只能在函数中体现
package main
var x, y int
var ( // 这种因式分解关键字的写法一般用于声明全局变量
a int
b bool
)
var c, d int = 1, 2
var e, f = 123, "hello"
//这种不带声明格式的只能在函数体中出现
//g, h := 123, "hello"
func main(){
g, h := 123, "hello"
println(x, y, a, b, c, d, e, f, g, h)
}
函数定义
func function_name( [parameter list] ) [return_types] {
函数体
}
数组定义
var var_name [size] var_type
var blance [10] float32
// 初始化数组
var blance = [10]int {1,2,3,4,5,6,7,8,9,10}
指针
指针变量是指向一个值得内存地址 类似于变量和常量,在使用指针变量前也需要声明这个指针
var ip *int
var fp *float32
var a int = 32
ip = &a
fmt.Printf("a 变量的地址是: %x\n", &a) // 指针的地址
fmt.Printf("*ip 变量的值: %d\n", *ip) // 指针的值
var var_name *var_type
空指针
当一个指针被定义之后没有赋值的话,它的值为nil nil指针也称为空指针
结构体
// 定义一个结构体
type struct_var_type struct {
member definition;
member definition;
member definition;
member definition;
}
// 声明结构体
var_name := struct_var_type {var1, var2, var3}
type Books struct {
title string
author string
subject string
book_id int
}
// 声明 Book1 为 Books 类型
var Book1 Books
Book1.title = "Go 语言"
Book1.author = "ydl"
Book1.subject = "Go语言学习"
Book1.book_id = 123
// 打印这个结构体
fmt.Printf( "Book 1 title : %s\n", Book1.title)
fmt.Printf( "Book 1 author : %s\n", Book1.author)
fmt.Printf( "Book 1 subject : %s\n", Book1.subject)
fmt.Printf( "Book 1 book_id : %d\n", Book1.book_id)
func printBook(book Books) {
fmt.Printf( "Book 1 title : %s\n", book.title)
fmt.Printf( "Book 1 author : %s\n", book.author)
fmt.Printf( "Book 1 subject : %s\n", book.subject)
fmt.Printf( "Book 1 book_id : %d\n", book.book_id)
}
// 结构体指针
var struct_pointer *Books
struct_pointer = &Book1
切片
声明一个未定义长度的数组
var var_name [] var_type
或者使用 make()来创建一个切片
var slice1 []type = make([]type, len)
// or
slice1 := make([]type, len)
// 初始化
slice1 :=[] int {1,2,3 }
类似于python中的切片,取值
s := slice1[start:]
s := slice1[start:end]
s := slice1[:end]
相关函数介绍
len() 获取长度
cap() 测量切片最长长度可以到达多少
append() 追加
copy() 拷贝切片
空切片
未初始化的切片,为nil,长度为0
语言范围 range
range 用于for循环中迭代数组array、切片slice、通道channel、集合map等元素
Map集合
- 无序的键值对
- 可以像数组和切片一样迭代
- 使用hash实现的
定义一个map集合
var map_var_name map[key_data_type] var_type
// 使用make函数
map_var := make(map[key_data_type]var_type)
类型转换
type_name(express)
go 接口类型
把所有具有共性的方法放置在一起,任何其他类型只需要实现这些方法就实现了这个接口
/* 定义接口 */
type interface_name interface {
method_name1 [return_type]
method_name2 [return_type]
method_name3 [return_type]
...
method_namen [return_type]
}
/* 定义结构体 */
type struct_name struct {
/* variables */
}
/* 实现接口方法 */
func (struct_name_variable struct_name) method_name1() [return_type] {
/* 方法实现 */
}
...
func (struct_name_variable struct_name) method_namen() [return_type] {
/* 方法实现*/
}
错误处理
errors.New("math: square root of negative number")
感想
-
其实语言还是有很多的通性的,在数据类型和流程控制方面有些差异,但是大致还是一个方向,可能数据类型更丰富了,流程控制更加的方便等 在语言方面增加了很多的特性,使得这个语言解决一些特定的场景需求,比如海量并发、高性能等
-
go 的发展很迅速,开源的库也很多,也有很多出名的开源项目,如:
docker容器、TiDB数据库、k8s(Kubernetes)容器编排技术 -
go的社区也比较活跃,在一些一线城市需求量比较大,高性能web服务,游戏后端开发等等
-
其实我自己开始学php开发的,开发一些web和后端api项目,对于我来说如果再学一些go的web开发,感觉对我的帮助不大,了解自身薄弱之处:
- 数据结构和算法
- 网络编程
- 异步、同步、io操作
- 设计模式
- 多线程
- 数据库
-
其实编程千变万化不离其中,离不开基础,而这些都是建筑高楼大厦的基础,很多人在开发过程中会遇到瓶颈,不知道如何提升,其实我们可以再次复习以前学过的知识, 温故而知新,读一本书我们可以了解到这本书讲的是什么,第二次读我们可以读到更多,作者写作意图,融入作者的思维,跟随作者置身其中,得到不一样的感受。开发学习亦是如此, 多学习几遍基础,我们会有不一样的感受,视野也会更加的广阔,切勿浮躁,走马观花。热门的框架学习固然重要,跟随时代的潮流,不落伍。但是学习框架也是有迹可循的,在后面我会 介绍如何去学一个框架,入门一个框架,源代码分析,思维导图等等。