<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                [TOC] [https://github.com/golang](https://github.com/golang) 手冊 [https://cloud.tencent.com/developer/section/1142075](https://cloud.tencent.com/developer/section/1142075) 下載地址 [http://mirrors.ustc.edu.cn/golang/](http://mirrors.ustc.edu.cn/golang/) # 優勢 * 可以直接編譯成機器碼,不依賴其他庫,glibc的版本有一定要求,部署就是扔一個文件上去 * 跨平臺編譯,如果你寫的代碼不包含cgo,那么就可以做到windows系統編譯linux的應用.go引用了plan9的代碼,這就是不依賴系統的信息 * 內嵌c支持,Go里面也可以直接包含c代碼,利用現有的豐富c庫 自動搜索所有函數并集中到一個.a文件 生成library時候是會自動把`$GOPATH/src/github.com/cyent/golang/example/stringutil/`下面所有.go文件里包含的函數集中到`stringutil.a`中(根據這些.go文件中的package xxx來自動加入到一個.a),因此如果存在相同的函數,會報錯提示重復 # 學習資料 go語言官網: https://golang.org/ go中文社區: https://studygolang.com/ go中文在線文檔: https://studygolang.com/pkgdoc # 命令源碼文件 如果一個源碼文件聲明屬于main包,并且包含一個無參數聲明且無結果聲明的main函數,那么它就是命令源碼文件 ~~~ package main import "fmt" func main() { fmt.Println("Hello, world!") } ~~~ # 命令行 * 編譯go代碼,生成一個可執行程序 ~~~ go build xxx.go ~~~ 然后這個程序就可以執行了 * 不生成可執行文件,直接運行 ~~~ go run xxx.go ~~~ * `go install` 配置GOPATH到src同級的絕對目錄`src/xx` 需要配置GOBIN 到src目錄執行go install就行,會生成2個目錄在src同級 自動生成pkg和bin pkg放平臺,bin放可執行程序 # 環境變量 * `src`存放源代碼(比如:.go .c .h .s等)? ?按照golang默認約定,go run,go install等命令的當前工作路徑(即在此路徑下執行上述命令)。 * `pkg`編譯時生成的中間文件(比如:.a)  golang編譯包時 * `bin`編譯后生成的可執行文件(為了方便,可以把此目錄加入到 $PATH 變量中,如果有多個gopath,那么使用`${GOPATH//://bin:}/bin`添加所有的bin目錄) 代碼目錄結構: GOPATH下的src目錄就是接下來開發程序的主要目錄,所有的源碼都是放在這個目錄下面,那么一般我們的做法就是一個目錄一個項目, 例如: $GOPATH/src/mymath 表示mymath這個應用包或者可執行應用,這個根據package是main還是其他來決定,main的話就是可執行應用,其他的話就是應用包,這個會在后續詳細介紹package `go install/go get`和 go的工具等會用到GOPATH環境變量 goroot在上面 ~~~ export GOPATH=/Users/hopkings/www/Go export GOBIN=$GOPATH/bin export PATH=$PATH:$GOBIN ~~~ **go get** 會做兩件事: 1. 從遠程下載需要用到的包 2. 執行go install `go get = git clone + go install` 從指定源上面下載或者更新指定的代碼和依賴,并對他們進行編譯和安裝 **go install** go install 會生成可執行文件直接放到bin目錄下,當然這是有前提的 你編譯的是可執行文件,如果是一個普通的包,會被編譯生成到pkg目錄下該文件是.a結尾 # go build 1. 運行go build命令時加入標記-x,這樣可以看到go build命令具體都執行了哪些操作。另外也可以加入-n,只查看具體操作不執行他們 2. 運行go build命令加入標記-v,這樣可以看到go build命令編譯源碼包的名稱,和-a標記搭配很有用 3. 執行該命令而且不加參數,會試圖把當前目錄作為代碼包編譯. `-a`所有涉及到代碼包都被編譯,不加只會編譯歸檔文件而不是最新的代碼包 # go get 從github下載后安裝到GOPATH第一個工作區的相應目錄中.如果存在GOBIN,那么僅包含命令元am文件代碼會裝到GOBIN那 -u: 下載并安裝代碼包,不論是否存在 -d: 只下載不安裝 -fix: 下載代碼包后先運行一個用于根據當前go版本修正代碼的工具,然后再安裝代碼包 -t: **同時下載測試所需的代碼包** -insecure: 允許通過非安全的網絡協議下載,比如http **uses insecure protocol** ~~~ export url='' export project='' git config --global url."git@${url}:".insteadOf "http://${url}/" go get -v -insecure "${url}${project}" ~~~ # go env ![](https://box.kancloud.cn/305b2452adbacf4e2dfdaa6087f4990f_804x728.png) # 查看編譯的依賴 mac上沒有ldd和strace mac對應的是otool和strace,需要root 查看動態鏈接庫`otool -L` ~~~ ldd 可執行文件 ~~~ ![](https://box.kancloud.cn/722e10006afbec8b3bad4a20439aa565_1350x582.png) 上圖中的三列數據分別代表: 1. 第一列:程序依賴的庫 2. 第二列:系統提供的對應庫 3. 第三列:庫加載的開始地址 通過對比第一列和第二列數據,可以分析程序依賴的庫和系統實際提供的庫,看兩者是否相匹配。 通過第三列數據,可以知道在當前的庫中的符號在對應的進程的地址空間中的開始位置 # 交叉編譯 ![](https://box.kancloud.cn/284d319c47a6d8154bdf737056ae901c_1268x404.png) 有效的`$GOOS`和`$GOARCH`組合如下 ~~~ $GOOS $GOARCH android arm darwin 386 darwin amd64 darwin arm darwin arm64 dragonfly amd64 freebsd 386 freebsd amd64 freebsd arm linux 386 linux amd64 linux arm linux arm64 linux ppc64 linux ppc64le linux mips linux mipsle linux mips64 linux mips64le netbsd 386 netbsd amd64 netbsd arm openbsd 386 openbsd amd64 openbsd arm plan9 386 plan9 amd64 solaris amd64 windows 386 windows amd64 ~~~ 交叉編譯主要是兩個編譯環境參數 `$GOOS` 和 `$GOARCH` 的設定 `$GOOS`代表編譯的目標系統,`$GOARCH`代表編譯的處理器體系結構 `$GOOS`可選值如下 ~~~ darwin dragonfly freebsd linux netbsd openbsd plan9 solaris windows ~~~ `$GOARCH`可選值如下 ~~~ 386 amd64 arm ~~~ Mac 下編譯 Linux 和 Windows 64位可執行程序 ~~~ CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build main.go CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build main.go ~~~ 在Linux系統下跨平臺編譯 ~~~shell CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build xxx.go ~~~ 在Windows系統下跨平臺編譯 ~~~shell set CGO_ENABLED=0 set GOARCH=386 set GOOS=windows go build xxx.go ~~~ 選擇性編譯 雖然golang 可以跨平臺編譯,但卻無法解決系統的差異性。總在一些時候我們會直接調用操作系統函數。相同功能編寫類似xxx_windows.go xxx.Linux.go文件,根據操作系統編譯對應源文件。而不是在文件中用if else規劃執行路徑。 要實現選擇性編譯需要在文件頂部增加構建標記。 ~~~ // +build ~~~ 此標記必須出現在文件頂部,僅由空行或其他注釋行開頭。也就是必須在Package 語句前。此標記后接約束參數,格式為 // +build A,B !C,D 逗號為且,空格為或,!為非。代表編譯此文件需符合 (A且B) 或 ((非C)且D) 。A和C的可選參數可參見本文上面的 $GOOS參數,B和D的可選參數可參見$GOARCH 。比如 ~~~ // +build !windows,386 //此文件在非windows操作系統 且386處理器時編譯 ~~~ 最后, Golang為跨系統運行的確是已經做得夠好了。沒有C C++的歷史包袱,但充分吸取了他們的諸多特點,為加快工作效率損失的軟件性能是值得的 # 編譯器 在網絡上的諸多教程中可能會看到下面的編譯命令 ~~~ CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build hello.go ~~~ 其中CGO\_ENABLED=0的意思是使用C語言版本的GO編譯器,參數配置為0的時候就關閉C語言版本的編譯器了。自從golang1.5以后go就使用go語言編譯器進行編譯了。在golang1.9當中沒有使用CGO\_ENABLED參數發現依然可以正常編譯。當然使用了也可以正常編譯。比如把CGO\_ENABLED參數設置成1,即在編譯的過程當中使用CGO編譯器,我發現依然是可以正常編譯的。 實際上如果在go當中使用了C的庫,比如`import "C"`默認使用go build的時候就會啟動CGO編譯器,當然我們可以使用CGO\_ENABLED=0來控制go build是否使用CGO編譯器。 # GOPROXY ~~~ export GOPROXY=https://goproxy.io ~~~ or ~~~ $env:GOPROXY = "https://goproxy.io" ~~~ ![](https://box.kancloud.cn/ee6a7034d5a6cc9d1e0d3023b0d50987_964x474.png) # 壓縮可執行文件 首先加上編譯參數`-ldflags` `-s`相當于strip掉符號表, 但是以后就沒辦法在gdb里查看行號和文件了。 `-w` 告知連接器放棄所有debug信息 ~~~ $ go build -ldflags '-w -s' ~~~ 使用upx壓縮,Linux、Mac和Win都有,這里以Mac為例 upx就是對可執行文件進行壓縮,然后可以已極快的速度解壓并運行 ~~~ $ brew install upx $ upx etcd-cli ~~~ Golang開發的程序都會比較大,這是因為Golang是靜態編譯的,編譯打包之后基本就不會再對其他類庫有依賴了,所以會比較大。舉個例子:C++程序可以調用dll,所以打包的時候可以不把dll打進去,包自然就小了。之前還有看到過有人使用`GO -> C -- dll --> C -> GO`的方式間接實現了Golang的偽動態鏈接 # go cache 通過運行`go env GOCACHE`命令來查看緩存目錄的路徑。緩存的數據總是能夠正確地反映出當時的各種源碼文件、構建環境、編譯器選項等等的真實情況。 一旦有任何變動,緩存數據就會失效,go 命令就會再次真正地執行操作。所以我們并不用擔心打印出的緩存數據不是實時的結果。go 命令會定期地刪除最近未使用的緩存數據,但是,如果你想手動刪除所有的緩存數據,運行一下`go clean -cache`命令就好了 # goland調試 菜單依次選擇“Run”->“Edit configurations”如下圖所示: ![](https://box.kancloud.cn/ad7b0561ffefc65d8219dc39324116e7_431x329.png) ![](https://box.kancloud.cn/47da02127e84f69d4eabf1ee1117482e_1098x583.png)
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看