zoukankan      html  css  js  c++  java
  • gotour源码阅读

    go-tour是一个web项目,具有很强的可读性。

    下面先看下里面的目录

    appengine:这个包是当你想把go-tour布置到GAE上的时候使用的安装,我们这里只是使用本地安装,所以这里的代码可以不看

    solutions:这个文件夹可以忽略,只是对文档中execise的答案,与go-tour网站无关

    talks:这个是作者做的关于go-tour的演讲放在这里面,也可以直接忽略

    static:这个文件夹是存放静态资源,js,css,html都是放在这里面

    tree:这个文件夹存放程序自动生成一个树的代码包。这个是具体的功能才使用到的,与网站无关

    wc:测试套件。这个是具体的练习题中才使用的到,与网站无关

    pic:对图片的处理包。这个是具体的练习题中才使用到的,与网站无关

    gotour:这个才是真正的go-tour的入口,main包在这里

    从gotour/local.go看起

    直接在全局变量中写了两个参数http和html。

    http说明是在哪个端口监听。

    html是说明是输出html页面还是打开,这个html是没有用的,估计作者想做这个功能来着,还没做完。

    init函数是将编译生成的可执行文件存放的临时文件夹设置好。

    进入main函数,有个uniq的chan int,这个是为了给临时文件做唯一标示的,会不断增长的。

    main中的uniq是一个id生成器,这个方法很常用

    var ( 
         // a source of numbers, for naming temporary files
         uniq = make(chan int)
    )
    
    func main() { 
         flag.Parse()
         // source of unique numbers
         go func() {
              for i := 0; ; i++ {
                   uniq <- i
              }
         }()
    }

    main中首先获取go-tour的目录,它是使用build包来获取,可以学之当做固定模板

    // find and serve the go tour files 
    p, err := build.Default.Import(basePkg, "", build.FindOnly)
    if err != nil {
        log.Fatalf("Couldn't find tour files: %v", err)
    }
    root := p.Dir

    下面就是使用http包做不同的路由了。

    有几个不同的路由器:

    / ,  /favicon.ico, /static/ , talk/,  kill

    kill是杀死一个running的命令。这里有个running是为了跑正在运行的程序

    run函数很好的演示了如何运行系统命令,并且输出结果

    好了,这里的main看完了,当你实际运行的时候你会发现,程序中对代码的编译实际上是使用/compile和/fmt两种。这两种访问路径是在goplay.go和fmt.go中定义的

    先看goplay.go

    直接在init()中写上了HandleFunc,这样也能更醒目地告诉所有人,这里的包是为了编译使用

    Compile函数中的具体实现步骤是用compile函数(local.go中)来实现的,后面就是json编码后输出。

    下面看main中的compile,main中有维持一个running结构,这里值得注意的是它使用的初始化直接在struct定义的时候加个var,这个可以记一下

    var running struct {

         sync.Mutex

         cmd *exec.Cmd

    }

    继续看compile,这个时候,参数request里面是包含要运行的go代码

    先将go代码放到临时文件中,然后bin是目标生成文件,src是源码文件

    第一步,将代码写入到src中

    第二步,运行go build,并使用-o 参数,将目标文件生成到bin中

    第三步,运行bin,输出结果(当然这个结果是有做一些处理,之类的commentRe的作用)

    第四步,删除src和bin这两个文件

    下面就看fmt.go

    对代码进行格式化应该也可以使用go fmt工具,但是这里不是这样使用的。

    同goplay.go一样,在init的时候设置了一个Handle

    然后使用gofmt函数对代码格式化,进到gofmt函数

    gofmt函数使用了go/token,go/parser对代码进行格式化,实际的工作就是:

    1 顺序化import包

    2 美化go代码

    哈哈,这里就是说go的程序能对自身(go程序)进行美化和运行(自举),这个感觉太爽了,使用的就是go/XXX的包

    这里的几个关键函数:

    token.NewFileSet() : 创建fset结构

    parser.ParseFile() : 解析go编码(这步最后的mode能制定是解析到什么地步)

    ast.SortImports() : 将import包进行排序

    printer.Fprint() : 美化工具

    这下代码就结束了,至于页面上出现的分页的效果等,都是js和css作用的结果,与服务器无关了。

    整个页面只需要3个代码文件(静态页面除外)!300行代码不到的量!(当然它更多的操作是在js中)少即是极多!

    实时了解作者更多技术文章,技术心得,请关注微信公众号“轩脉刃的刀光剑影”

    本文基于署名-非商业性使用 3.0许可协议发布,欢迎转载,演绎,但是必须保留本文的署名叶剑峰(包含链接http://www.cnblogs.com/yjf512/),且不得用于商业目的。如您有任何疑问或者授权方面的协商,请与我联系

  • 相关阅读:
    - (id)initWithCoder:(NSCoder *)decoder 的参数的作用
    pch定义的宏,文件引用报错,use of undeclared identifier
    tableView代理方法的调用时间,(主要是heightForRowAtIndexPath和cellForRowAtIndexPath调用时间)
    Receiver 'NSManagedObjectContext' for class message is a forward declaration 错误的解决方案
    delegate、notification、KVO的使用场景总结
    UIGestureRecognizer手势和scrollview冲突的简单解决
    CGAffineTransform中setTransform的几种类型以及注意事项
    使用"vuedraggable"插件实现列表排序功能;
    aliplayer的使用
    自制时间轴组件封装
  • 原文地址:https://www.cnblogs.com/yjf512/p/2816480.html
Copyright © 2011-2022 走看看