分享
  1. 首页
  2. 文章

go

THZXQ · · 2115 次点击 · · 开始浏览
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

语言简介

go是强类型静态语言,也就是说在编译阶段就确定变量类型,并且转换类型需要显示转换,它有如下几个特点:
  1. 跟脚本语言相似,容易上手、容易流行
  2. 底层是c,性能好
  3. 对goroutine调度进行了封装,即在语言层面支持协程,对于开发者,用起来方便

编译过程

  • go以包的形式管理源程序,每个包至少包含一个go文件。编译的时候会把main包生成可执行文件放到bin目录下,其他包生成xx.a包文件放到pkg目录下。

可执行程序初始化过程

  • 先执行main包的go文件,对依赖的包递归执行import、常量和变量初始化、init函数流程之后,初始化main自己的常量和变量、再依次执行init函数和main函数,示意图如下(竟然不能直接放图片,????):
    https://github.com/JJAWX/imag...

go文件基本构成

package xx

表明这个go文件是属于哪个包,这条语句是必须写的,因为go是以package的形式管理源文件的

import xx

引入当前文件依赖的包,包的路径只可以是相对路径,eg:"xxx/decorator",go查找包的过程是先在$GOROOT/src($GOROOT是go的安装路径,默认在/usr/local/go下)文件夹下找,如果找不到就从$GOPATH/src($GOPATH是go工作空间路径,当前工作代码所在的go文件夹路径)文件下找。

var/const声明初始化

整型
 var test int = 123
布尔
 var test bool = true
字符串
 var test string = "abc"
数组(数组必须指定长度,否则属于切片,不赋值,指定长度默认[0,0])
 var test [2]int
 test[0] = 6
 test[1] = 8
切片(没指定长度的数组或者用make初始化的数组)
 // 添加元素方式一
 var test = make([]string, 0)
 test = append(test, 2)
 // 添加元素方式二
 var test = make([]string, 2)
 test[0] = "123"
 test[1] = "456"
结构体
 type TestA struct {
 c int
 }
 type Test struct {
 a int
 b string
 c int
 TestA
 }
 var test = Test{6, "aa", 8, TestA{3}} // 或者不初始化:var test Test
channel
 test := make(chan int)
 go func(){ test <- 1 }()
 fmt.Printf("aaa: %+v", <-test)
interface{}(一个接口可以拥有任何实现了它所有方法的类型的属性,空接口代表所有对象都实现了它,也就是说用它可以接收任何类型)
 type Test interface{
 Say()
 }
 type TestA struct{}
 func (a TestA) Say(){
 fmt.Printf("hello")
 } 
 var testa TestA
 var test Test
 test = testa // 接口类型,
指针
 var testPtr *int // 定义了没有分配到任何变量时,为空指针
map(默认是nil,不初始化,不能存任何东西)
 // 方式一
 var test = make(map[string]string)
 test["a"] = "123"
 
 // 方式二
 var test = map[string]string{}
 test["a"] = "123"
 
 // 方式三
 test := make(map[string]string)
 test["a"] = "123"

init函数

初始化一些全局变量,供所属包或者所有包调用

main函数

属于main包,是程序的入口,和main包是一一对应的关系。

其他函数

业务子逻辑,处理客户端的GET、POST、PUT、DELETE等请求,get请求使用url库对请求参数进行解析,跟它相关的几个方法是:DefaultQuery、Query、QueryArray,;GET、POST、PUT、DELETE请求的话使用的是gin框架的model binding模型,相关的几个方法是:BindWith、BindJSON、Bind、它们底层都使用了MustBindWith这个方法, 这个方法接收两个参数,一个是要解析的struct(ps:解析的对象必须是struct或者是指向struct的指针),另一个是binding,由跟Bind相关的几个函数指定,指定的方式区别如下:

  • BindWith: 可接收两个参数,一个是要解析的对象,一个是binding
  • BindJSON: 只接收一个参数,是要解析的对象,使用的binding是bing.JSON,它对要解析的数据是怎么处理的呢,从req.body中拿出要解析的数据,使用reflect反射对要解析的对象类型进行判断,然后从req.body中取要的数据
  • Bind: 接收一个参数,会根据请求的method和content-type判断使用什么binding来解决。

逻辑处理完成,需要使用context.JSON(关键:json.Marshal)或context.HTML(ps: 分别接收三个参数:状态码、模版路径、模版数据)将结果返回给客户端。

go异常捕捉处理

和异常处理相关的几个关键字:defer(return的时候执行)、recover(捕捉异常)、panic(err)(抛出异常),需要注意的地方是如果子协程不捕捉处理异常,就会报到主线程,由主线程处理,但是子协程会异常退出。

 func example () {
 defer func() {
 if err := recover(); err != nil {
 fmt.Printf("error: %+v", err)
 } else {
 fmt.Printf("抛出了一个nil")
 }
 }()
 // panic(nil) // 结果:抛出了一个nil
 panic("fail") // 结果: error: failed
 }

go并发

go关键字 + channel

 // 无缓冲通道
 func example () {
 test := make(chan int)
 go func(){
 test <- 1
 }()
 fmt.Printf("channel value: %+v", <-test)
 }
 // 执行结果
 channel value: 1
 
 // 缓冲通道
 func example () {
 test := make(chan int, 2)
 go func(){
 for i := 0; i < 2; i++ {
 test <- i
 }
 close(test) // 很重要,需要手动关闭,要不然会造成死锁
 }()
 for ch := range test {
 fmt.Printf("channel value: %+v", ch)
 fmt.Println("")
 }
 }
 // 执行结果
 channel value: 0
 channel value: 1

sync.WaitGroup(例子 + 结果)

 func example () {
 var wg sync.WaitGroup
 for i := 0; i < 2; i++ {
 m := i // 考虑到主线程释放控制权之后协程才执行,缓存i
 wg.Add(1)
 go func(){
 defer func(){
 fmt.Println("ending...")
 wg.Done()
 }()
 fmt.Println(fmt.Sprintf("当前循环到哪里了: %+v", m))
 }()
 }
 
 fmt.Println("example...")
 wg.Wait()
 }
 // 执行结果
 example...
 当前循环到哪里了: 0
 ending...
 当前循环到哪里了: 1
 ending...

有疑问加站长微信联系(非本文作者)

本文来自:Segmentfault

感谢作者:THZXQ

查看原文:go

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

关注微信
2115 次点击
暂无回复
添加一条新回复 (您需要 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传

用户登录

没有账号?注册
(追記) (追記ここまで)

今日阅读排行

    加载中
(追記) (追記ここまで)

一周阅读排行

    加载中

关注我

  • 扫码关注领全套学习资料 关注微信公众号
  • 加入 QQ 群:
    • 192706294(已满)
    • 731990104(已满)
    • 798786647(已满)
    • 729884609(已满)
    • 977810755(已满)
    • 815126783(已满)
    • 812540095(已满)
    • 1006366459(已满)
    • 692541889

  • 关注微信公众号
  • 加入微信群:liuxiaoyan-s,备注入群
  • 也欢迎加入知识星球 Go粉丝们(免费)

给该专栏投稿 写篇新文章

每篇文章有总共有 5 次投稿机会

收入到我管理的专栏 新建专栏