Go语言总结和学习指南

jopen 9年前

早在2009年11月google刚推出go语言的时候,在好奇心的驱使下,就下载体验过。那时的感觉是语法比较奇怪,相关的资源较少,并且习惯了动态语言Python。虽然它一出来就宣称是一种为并发能力而生的语言,但是感觉Python已经能够满足自己的日常的开发要求,所以并不感觉它有什么优势。
但是也在持续的关注它一点一点的发展:发现越来越多的项目采用go作为开发语言来开发程序,也越来越多的程序员,包括Python的程序员,在使用go语言。如今,go1.4 已经支持Android开发,有空又把go拿出来试用了把,当初它的为了追求语法上的简洁而搞得比较古怪的语法变得不再那么让人不舒服,也开始体会到它的诸多优势,下面是我总结的Go的优点:
1、Go与C/C++一样,都是可以把代码直接编译成二进制可执行程序,但是和C/C++不同的是go自带垃圾收集器,这可以在不损失太大的性能的情况下大大的简化程序的设计。
2、Go和Python一样内置强大的方便使用的数据结构
3、丰富的库和详细的开发文档:一种语言好不好用,除了语言本身外,还在于提供强大易用的库支持,一个好的社区以及社区所维护的丰富的文档。在这方面,个人认为Go做得相当不错,文档写得很详细,很多还配有示例代码。
4、大大简化了并发程序的开发,使用channel来开发并发程序真的是变得非常方便

5、简洁的语法,尽量减少程序员打字的负担,提高开发效率。


再来看下我总结的Go和Python两者之间的对比:

1、其实Go和Python的有些设计理念还是一样的,比如正像它的简短的名字一样,Go追求代码的简洁,甚至到了有些苛刻的地步。

2、不仅在语法上,Go尽量减少不必要的按键操作,它的垃圾收集机制,它的并发编程的能力,无疑大大方便了程序员的开发。

3、仔细分析Go和Python还有相似之处,如range函数,再如filepath.Walk等等。

4、 虽然开发者没有明说,但无疑Go是借鉴了Python在易用性方面的经验的,这也是为什么很多Python的程序员转而使用Go的原因。


接下来看下Go的相关资源:

1、官方网点:http://golang.org/

2、官方的Go语言入门指南:http://tour.golang.org/welcome/1

该指南以详尽的例子来引导你学习和了解Go语言的特性, 没有比这更好的Go的入门学习资源了。这些示例分成三个部分:

1)、基础:主讲是Go的一些基本概念,流控制语句和一些内置的数据结构:slice和map的使用

2)、接下来讲方法(Methods)和接口(interfaces)
3)、再接下来讲并发(concurrency)

这些例子需要有些耐心来熟悉,尤其是interface和concurrency在刚接触时需要点时间去消化。等熟悉完所有的例子,Go也算是入门了。

3、代码路径:https://github.com/golang/go

要自己体验一下编译代码或者研究下Go代码的可以下载下来看看,不过,对于初学者来说,可能太早了。

4、开发文档:http://golang.org/pkg/

不用多说,Go开发人员必备。


再拉下来看下在网上收集了一些常用的例子:
1、 Go语言实现http共享
    package main        import (                "net/http"                "os"                "strings"        )        func shareDir(dirName string,port string,ch chan bool){                h := http.FileServer(http.Dir(dirName))                err := http.ListenAndServe(":"+port,h)                if err != nil {                        println("ListenAndServe : ",err.Error())                        ch <- false                }        }        func main(){                ch := make(chanbool)                port := "8000"//Default port                iflen(os.Args)>1 {                        port = strings.Join(os.Args[1:2],"")                }                go shareDir(".",port,ch)                println("Listening on port ",port,"...")                bresult := <-ch                iffalse == bresult {                        println("Listening on port ",port," failed")                }        }  

链接:http://www.cnblogs.com/MikeZhang/archive/2012/03/13/httpShareGolang20120312.html


2、 Go 的文件与目录遍历方法 - path/filepath.Walk
    package main        import (            "path/filepath"            "os"            "fmt"            "flag"        )        func WalkFunc(path string, info os.FileInfo, err error) error {            return nil        }        type Walker struct {            directories []string            files       []string        }        func main() {            flag.Parse()        //    root := flag.Arg(0)            walker := new (Walker)            path := "."            filepath.Walk(path, func(path string, info os.FileInfo, err error) error {                    if err != nil { return err }                    if info.IsDir() {                        walker.directories = append(walker.directories, path)                    } else {                        walker.files = append(walker.files, path)                    }                    return nil                })            fmt.Printf("found %d dir and  %d files\n", len(walker.directories), len(walker.files))            for i:=0;i<len(walker.files);i+=1 {                fmt.Println(walker.files[i])            }        }  

参考链接:http://caryagos.com/press/go-walk-files-diretories/


3、 简单的TCP代理服务器
netfwd.go
    package main        import (        "net"        "fmt"        "io"        "os"        )        func main() {        if len(os.Args) != 3 {        fatal("usage: netfwd localIp:localPort remoteIp:remotePort")        }        localAddr := os.Args[1]        remoteAddr := os.Args[2]        local, err := net.Listen("tcp", localAddr)        if local == nil {        fatal("cannot listen: %v", err)        }        for {        conn, err := local.Accept()        if conn == nil {        fatal("accept failed: %v", err)        }        go forward(conn, remoteAddr)        }        }                 func forward(local net.Conn, remoteAddr string) {        remote, err := net.Dial("tcp",remoteAddr)        if remote == nil {        fmt.Fprintf(os.Stderr, "remote dial failed: %v\n", err)        return        }        go io.Copy(local, remote)        go io.Copy(remote, local)        }                 func fatal(s string, a ... interface{}) {        fmt.Fprintf(os.Stderr, "netfwd: %s\n", fmt.Sprintf(s, a))        os.Exit(2)        }  

4、命令行参数解析

go版本:
package main    import (            "flag"            "fmt"    )    var (            ip = flag.String("host","127.0.0.1","ip address")            port = flag.String("port","8000","listen port")    )    func main() {            flag.Parse()            fmt.Println("ip   : ",*ip)            fmt.

python版本:
#! /usr/bin/python    import getopt,sys    if __name__ == "__main__":        try:            opts,args = getopt.getopt(sys.argv[1:],"h:p:",["host=","port="])        except getopt.GetoptError:            print "Usage :"            print "-h arg , --host=arg : set ip address"            print "-p arg , --port=arg : set port"            sys.exit(1)        host = "127.0.0.1"        port = 8000        for opt,arg in opts:            if opt in ("-h","--host"):                host = arg            if opt in ("-p","--port"):                port = arg        print "ip   : ",host        print "port : ",port 

参考链接:

http://www.cnblogs.com/MikeZhang/archive/2012/09/07/argsTest20120907.html

5、 调用其它程序并得到程序输出(go和python)
go
    package main        import (            "os/exec"            "fmt"        )        func main(){            cmd := exec.Command("ls", "-l")            buf, err := cmd.Output()            fmt.Printf("%s\n%s",buf,err)        }  

python
    import os        var = os.popen('ls -l').read()        print var  

6、Go语言文件操作
写文件
    package main        import (                "os"                "fmt"        )        func main() {                userFile := "test.txt"                fout,err := os.Create(userFile)                defer fout.Close()                if err != nil {                        fmt.Println(userFile,err)                        return                }                for i:= 0;i<10;i++ {                        fout.WriteString("Just a test!\r\n")                        fout.Write([]byte("Just a test!\r\n"))                }        }  

读文件
    package main        import (                "os"                "fmt"        )        func main() {                userFile := "test.txt"                fin,err := os.Open(userFile)                defer fin.Close()                if err != nil {                        fmt.Println(userFile,err)                        return                }                buf := make([]byte, 1024)                for{                        n, _ := fin.Read(buf)                        if 0 == n { break }                        os.Stdout.Write(buf[:n])                }        }  

删除文件
    func Remove(name string) Error  

具体见官网:http://golang.org/pkg/os/#Remove


7、 Golang通过Thrift框架完美实现跨语言调用
http://my.oschina.net/u/572653/blog/165285


最后,献上《Go语言之父谈Go:大道至简》来结束这篇文章:
在这篇文章里,Go语言之父宣称:Go的目标是解放程序员!我们已经看到了Go在解决程序员所作的努力,但是什么时候能够解放程序员,我们还要试目以待,呵呵呵。

2015,go,let's go.

来自:http://blog.csdn.net/i2cbus/article/details/42399151