diff --git a/de/01.2.md b/de/01.2.md index c2d7021a..dc028588 100644 --- a/de/01.2.md +++ b/de/01.2.md @@ -92,13 +92,13 @@ Um die Anwendung zu kompilieren, müssen wir zurück in das Verzeichnis, in welc ## Installation von Paketen Dritter (Remote Packages) -Go umfasst ein Werkzeug zum Installieren von Remote Packages, also Paketen die von anderen Programmierern erstellt wurden. Mit dem Befehl `go get` kannst Du diese für die eigene Nutzung installieren. Es unterstützt die meisten Open Source Communities wie Github, Google Code, Bitbucket und Launchpad. +Go umfasst ein Werkzeug zum Installieren von Remote Packages, also Paketen die von anderen Programmierern erstellt wurden. Mit dem Befehl `go get` kannst Du diese für die eigene Nutzung installieren. Es unterstützt die meisten Open Source Communities wie GitHub, Google Code, Bitbucket und Launchpad. go get github.com/astaxie/beedb Du kannst `go get -u …` nutzen, um ein Remote Package zu aktualisieren. Zugleich werden auch alle benötigten Abhängigkeiten mit installiert. -Dieser Befehl nutzt verschiedene Versionskontrollsysteme für die verschiedenen Open Source Plattformen. So wird beispielsweise `git` für Github und `hg` für Google Code verwendet. Daher musst Du zuerst die entsprechenden Versionskontrollsysteme installieren, ehe Du `go get` nutzen kannst. +Dieser Befehl nutzt verschiedene Versionskontrollsysteme für die verschiedenen Open Source Plattformen. So wird beispielsweise `git` für GitHub und `hg` für Google Code verwendet. Daher musst Du zuerst die entsprechenden Versionskontrollsysteme installieren, ehe Du `go get` nutzen kannst. Nach dem Ausführen der oben gezeigten Befehle, sollte die Orderstruktur etwa so aussehen. diff --git a/de/01.3.md b/de/01.3.md index 07f5443a..a1ef5a72 100644 --- a/de/01.3.md +++ b/de/01.3.md @@ -43,7 +43,7 @@ Dieser Befehl löscht alle Dateien, die vom Kompiler generiert wurden, einschlie DIR.test(.exe) // Generiert von go test -c MAINFILE(.exe) // Generiert von go build MAINFILE.go -Überlicherweise nutze ich diese Befehle zum Säubern von Projekten, bevor ich diese auf Github hochlade. Sie sind nützlich für lokale Tests, aber nutzlos zur Versionskontrolle. +Überlicherweise nutze ich diese Befehle zum Säubern von Projekten, bevor ich diese auf GitHub hochlade. Sie sind nützlich für lokale Tests, aber nutzlos zur Versionskontrolle. ## go fmt und gofmt @@ -56,10 +56,10 @@ Wir nutzen üblicherweise `gofmt -w` statt `go fmt`. Somit wird Deine Quellcoded ## go get -Dieser Befehl ermöglicht es, Remote Packages herunterzuladen. Bisher untersützt es Bitbucket, Github, Google Code und Launchpad. Es geschehen zwei Dinge, nachdem wir den Befehl ausgeführt haben. Als erstes lädt Go den Quellcode herunter und führt danach `go install` aus. Bevor Du `go get` nutzt, solltest Du vorher die benötigten Versionskontrollsysteme herunterladen. +Dieser Befehl ermöglicht es, Remote Packages herunterzuladen. Bisher untersützt es Bitbucket, GitHub, Google Code und Launchpad. Es geschehen zwei Dinge, nachdem wir den Befehl ausgeführt haben. Als erstes lädt Go den Quellcode herunter und führt danach `go install` aus. Bevor Du `go get` nutzt, solltest Du vorher die benötigten Versionskontrollsysteme herunterladen. BitBucket (Mercurial und Git) - Github (Git) + GitHub (Git) Google Code (Git, Mercurial, Subversion) Launchpad (Bazaar) diff --git a/de/12.3.md b/de/12.3.md index 8f46bd75..5b1108aa 100644 --- a/de/12.3.md +++ b/de/12.3.md @@ -4,7 +4,7 @@ When our web application is finally production ready, what are the steps necessa ## Daemons -Currently, Go programs cannot cannot be run as daemon processes (for additional information, see the open issue on github [here](https://github.com/golang/go/issues/227)). It's difficult to fork existing threads in Go because there is no way of ensuring a consistent state in all threads that have been used. +Currently, Go programs cannot cannot be run as daemon processes (for additional information, see the open issue on GitHub [here](https://github.com/golang/go/issues/227)). It's difficult to fork existing threads in Go because there is no way of ensuring a consistent state in all threads that have been used. We can, however, see many attempts at implementing daemons online, such as in the two following ways; diff --git a/de/14.4.md b/de/14.4.md index 2bc3cf84..15f20a88 100644 --- a/de/14.4.md +++ b/de/14.4.md @@ -56,7 +56,7 @@ OAuth and OAuth 2 are currently two of the most popular authentication methods. github.com/bradrydzewski/go.auth -The code below demonstrates how to use this library to implement OAuth authentication in Beego using our Github credentials: +The code below demonstrates how to use this library to implement OAuth authentication in Beego using our GitHub credentials: 1. Let's add some routes @@ -147,7 +147,7 @@ After clicking "Authorize app", the following screen appears: ![](images/14.4.github3.png?raw=true) -Figure 14.6 authorized Github information gets displayed after the login page +Figure 14.6 authorized GitHub information gets displayed after the login page ## Custom authentication diff --git a/en/01.2.md b/en/01.2.md index 06adf944..4c794ada 100644 --- a/en/01.2.md +++ b/en/01.2.md @@ -95,13 +95,13 @@ To compile this application, you need to switch to the application directory, wh ## Install remote packages -Go has a tool for installing remote packages, which is a command called `go get`. It supports most open source communities, including Github, Google Code, BitBucket, and Launchpad. +Go has a tool for installing remote packages, which is a command called `go get`. It supports most open source communities, including GitHub, Google Code, BitBucket, and Launchpad. go get github.com/astaxie/beedb You can use `go get -u …` to update your remote packages and it will automatically install all the dependent packages as well. -This tool will use different version control tools for different open source platforms. For example, `git` for Github and `hg` for Google Code. Therefore, you have to install these version control tools before you use `go get`. +This tool will use different version control tools for different open source platforms. For example, `git` for GitHub and `hg` for Google Code. Therefore, you have to install these version control tools before you use `go get`. After executing the above commands, the directory structure should look like following. diff --git a/en/01.3.md b/en/01.3.md index 9ddb16bb..f3eb1650 100644 --- a/en/01.3.md +++ b/en/01.3.md @@ -55,10 +55,10 @@ We usually use `gofmt -w` instead of `go fmt`. The latter will not rewrite your ## go get -This command is for getting remote packages. So far, it supports BitBucket, Github, Google Code and Launchpad. There are actually two things that happen after we execute this command. The first thing is that Go downloads the source code, then executes `go install`. Before you use this command, make sure you have installed all of the related tools. +This command is for getting remote packages. So far, it supports BitBucket, GitHub, Google Code and Launchpad. There are actually two things that happen after we execute this command. The first thing is that Go downloads the source code, then executes `go install`. Before you use this command, make sure you have installed all of the related tools. BitBucket (Mercurial Git) - Github (git) + GitHub (git) Google Code (Git, Mercurial, Subversion) Launchpad (Bazaar) diff --git a/en/02.1.md b/en/02.1.md index 63e1e881..2aab7016 100644 --- a/en/02.1.md +++ b/en/02.1.md @@ -23,7 +23,7 @@ To mitigate all the problems that Google faced with current tools, they wrote a Go was designed with concurrency in mind, please note that parallelism != concurrency, there is an [amazing post](https://blog.golang.org/concurrency-is-not-parallelism) by Rob Pike on the [golang blog](https://blog.golang.org/), you will find it there, it is worth a read. -Another very important change that is the concept of `GOPATH`. Gone are the days when you had to create a folder called `code` and then create workspaces for eclipse and what not. Now you have to keep one folder tree for go code which will be updated by the package manager automatically. It is also recommended to create folders with either a custom domain or the github domain, for example I created a task manager using golang so I created a set of folders +Another very important change that is the concept of `GOPATH`. Gone are the days when you had to create a folder called `code` and then create workspaces for eclipse and what not. Now you have to keep one folder tree for go code which will be updated by the package manager automatically. It is also recommended to create folders with either a custom domain or the GitHub domain, for example I created a task manager using golang so I created a set of folders `~/go/src/github.com/thewhitetulip/Tasks` **Note:** In *nix systems `~` stands for home directory, which is the windows equivalent of `C:\\Users\\username`. diff --git a/en/12.3.md b/en/12.3.md index d9919a06..77cac455 100644 --- a/en/12.3.md +++ b/en/12.3.md @@ -4,7 +4,7 @@ When our web application is finally production ready, what are the steps necessa ## Daemons -Currently, Go programs cannot be run as daemon processes (for additional information, see the open issue on github [here](https://github.com/golang/go/issues/227)). It's difficult to fork existing threads in Go because there is no way of ensuring a consistent state in all threads that have been used. +Currently, Go programs cannot be run as daemon processes (for additional information, see the open issue on GitHub [here](https://github.com/golang/go/issues/227)). It's difficult to fork existing threads in Go because there is no way of ensuring a consistent state in all threads that have been used. We can, however, see many attempts at implementing daemons online, such as in the two following ways; diff --git a/en/14.4.md b/en/14.4.md index 79b61675..5c7e754d 100644 --- a/en/14.4.md +++ b/en/14.4.md @@ -56,7 +56,7 @@ OAuth and OAuth 2 are currently two of the most popular authentication methods. github.com/bradrydzewski/go.auth -The code below demonstrates how to use this library to implement OAuth authentication in Beego using our Github credentials: +The code below demonstrates how to use this library to implement OAuth authentication in Beego using our GitHub credentials: 1. Let's add some routes @@ -147,7 +147,7 @@ After clicking "Authorize app", the following screen appears: ![](images/14.4.github3.png?raw=true) -Figure 14.6 authorized Github information gets displayed after the login page +Figure 14.6 authorized GitHub information gets displayed after the login page ## Custom authentication diff --git a/es/01.2.md b/es/01.2.md index ed009b0d..f1cf5637 100644 --- a/es/01.2.md +++ b/es/01.2.md @@ -90,13 +90,13 @@ Para compilar esta aplicación necesitas cambiar al directorio de la aplicación ``` ## Instala paquete remotos -Go tiene una herramienta para instalar paquetes remotos, es el comando llamado `go get`. Soporta la mayoría de comunidades de código libre, incluyendo Github, Google Code, BitBucket y Launchpad. +Go tiene una herramienta para instalar paquetes remotos, es el comando llamado `go get`. Soporta la mayoría de comunidades de código libre, incluyendo GitHub, Google Code, BitBucket y Launchpad. ``` go get github.com/astaxie/beedb ``` Puedes usar `go get -u …` para actualizar tus paquetes remotos e incluso instalará todas sus dependencias. -Esta herramienta usará diferente herramientas de control de versiones para las diferentes plataformas de código libre. Por ejemplo, `git` para Github y `hg` para Google Code. Debido a esto, debes instalar estas herramientas de control de versiones antes de usar `go get`. +Esta herramienta usará diferente herramientas de control de versiones para las diferentes plataformas de código libre. Por ejemplo, `git` para GitHub y `hg` para Google Code. Debido a esto, debes instalar estas herramientas de control de versiones antes de usar `go get`. Después de ejecutar los comandos anteriormente descritos, la estructura de directorios debería verse de la siguiente forma: ``` diff --git a/es/01.3.md b/es/01.3.md index 5374cddd..8023205e 100644 --- a/es/01.3.md +++ b/es/01.3.md @@ -53,10 +53,10 @@ Usualmente usamos `gofmt -w` en vez de `go fmt`. El último, no rescribirá tus ## go get -Este comando es para obtener paquetes remotos. Hasta el momento soporta BitBucket, Github, Google Code y Launchpad. Actualmente existen dos cosas que suceden después de ejecutar este comando. La primera es que Go descarga el código fuente, luego ejecuta `go install`. Antes de que utilices este comando, asegúrate que tienes instaladas todas las herramientas relacionadas. +Este comando es para obtener paquetes remotos. Hasta el momento soporta BitBucket, GitHub, Google Code y Launchpad. Actualmente existen dos cosas que suceden después de ejecutar este comando. La primera es que Go descarga el código fuente, luego ejecuta `go install`. Antes de que utilices este comando, asegúrate que tienes instaladas todas las herramientas relacionadas. ``` BitBucket (Mercurial Git) - Github (git) + GitHub (git) Google Code (Git, Mercurial, Subversion) Launchpad (Bazaar) ``` diff --git a/es/02.1.md b/es/02.1.md index af0a447a..2220a75f 100644 --- a/es/02.1.md +++ b/es/02.1.md @@ -23,7 +23,7 @@ Entonces para mitigar todos los problemas que Google enfrentó con las herramien Go fue diseñado con la concurrencia en mente, por favor note que paralelismo != concurrencia. Hay un post maravilloso escrito por Bob Pike en el blog de Go, blog.golang.org, que usted encontraréa ahí y vale la pena leerlo. -Otro cambio muy importante que Go trajo a la programación y que yo personalmente amo, es le concepto de `GOPATH`, los tiempos donde tenías que crear una carpeta llamada code y entonces crear espacios de trabajo para eclipse y otros. Ahora usted puede tener un árbol de carpetas para el código en Go y se mantendrá actualizado automáticamente por el administrador de paquetes. También bajo el código que estamos recomendando crear carpetas con cada dominio específico o el dominio de github, por ejemplo yo creé un manejador de tareas usando Go, entonces creé un conjunto de carpetas +Otro cambio muy importante que Go trajo a la programación y que yo personalmente amo, es le concepto de `GOPATH`, los tiempos donde tenías que crear una carpeta llamada code y entonces crear espacios de trabajo para eclipse y otros. Ahora usted puede tener un árbol de carpetas para el código en Go y se mantendrá actualizado automáticamente por el administrador de paquetes. También bajo el código que estamos recomendando crear carpetas con cada dominio específico o el dominio de GitHub, por ejemplo yo creé un manejador de tareas usando Go, entonces creé un conjunto de carpetas `~/go/src/github.com/thewhitetulip/Tasks` Nota: En sistemas * nix `~` se refiere al directorio del usuario, que en windows es equivalente a `C:\\Users\\username` Ahora el `~/go/` es el universo de código Go en su máquina, este es solo una significante mejora en comparación con otros lenguajes, entonces podemos almacenar código eficientemente sin molestias, esto puede parecer raro al comienzo pero tiene un montón de sentido a comparación de los nombres de paquete en otros lenguajes que usan sistemas como el del dominio inverso. diff --git a/fa/working/01.2.md b/fa/working/01.2.md index 925a4229..f1dfe0ce 100644 --- a/fa/working/01.2.md +++ b/fa/working/01.2.md @@ -95,13 +95,13 @@ func main() { ## نصب بسته‌های ریموت -Go has a tool for installing remote packages, which is a command called `go get`. It supports most open source communities, including Github, Google Code, BitBucket, and Launchpad. +Go has a tool for installing remote packages, which is a command called `go get`. It supports most open source communities, including GitHub, Google Code, BitBucket, and Launchpad. go get github.com/astaxie/beedb You can use `go get -u …` to update your remote packages and it will automatically install all the dependent packages as well. -This tool will use different version control tools for different open source platforms. For example, `git` for Github and `hg` for Google Code. Therefore, you have to install these version control tools before you use `go get`. +This tool will use different version control tools for different open source platforms. For example, `git` for GitHub and `hg` for Google Code. Therefore, you have to install these version control tools before you use `go get`. After executing the above commands, the directory structure should look like following. diff --git a/fa/working/01.3.md b/fa/working/01.3.md index d8e7beee..9340a805 100644 --- a/fa/working/01.3.md +++ b/fa/working/01.3.md @@ -55,10 +55,10 @@ We usually use `gofmt -w` instead of `go fmt`. The latter will not rewrite your ## go get -This command is for getting remote packages. So far, it supports BitBucket, Github, Google Code and Launchpad. There are actually two things that happen after we execute this command. The first thing is that Go downloads the source code, then executes `go install`. Before you use this command, make sure you have installed all of the related tools. +This command is for getting remote packages. So far, it supports BitBucket, GitHub, Google Code and Launchpad. There are actually two things that happen after we execute this command. The first thing is that Go downloads the source code, then executes `go install`. Before you use this command, make sure you have installed all of the related tools. BitBucket (Mercurial Git) - Github (git) + GitHub (git) Google Code (Git, Mercurial, Subversion) Launchpad (Bazaar) diff --git a/fr/01.2.md b/fr/01.2.md index cfd9b6dd..3a90256e 100644 --- a/fr/01.2.md +++ b/fr/01.2.md @@ -115,14 +115,14 @@ Vous devriez voir le contenu suivant dans votre temrinal: ## Installer des paquets distants Go a un outil pour installer des paquets distants, qui est l'outil `go get`.Il supporte la majorité des communautés libres, comme -Github, Google Code, BitBucket, et Launchpad. +GitHub, Google Code, BitBucket, et Launchpad. go get github.com/astaxie/beedb >Vous pouvez utiliser `go get -u` pour mettre à jour vos paquets distants, cela mettra aussi à jour les dépendances. Vous obtiendrez le code source des paquets désirés grâce à cette commande, depuis différentes plate-formes, utilisant chacune leur système de gestion de version. -Par exemple, `git` pour Github et `hg` pour Google Code. Ainsi vous devrez au préalable installer le client du système de gestion de version approprié +Par exemple, `git` pour GitHub et `hg` pour Google Code. Ainsi vous devrez au préalable installer le client du système de gestion de version approprié avant d'utiliser`go get`. Après avoir utilisé les commandes précédentes, votre structure de dossier devrait ressembler à celle-ci: diff --git a/fr/01.3.md b/fr/01.3.md index 17858cb0..6e55c99a 100644 --- a/fr/01.3.md +++ b/fr/01.3.md @@ -69,13 +69,13 @@ Ce dernier ne modifie pas vos fichiers source après formattage. `gofmt -w src` ## go get -Cette commande récupère des paquets distants. Sont supportés BitBucket, Github, Google Code et Launchpad. +Cette commande récupère des paquets distants. Sont supportés BitBucket, GitHub, Google Code et Launchpad. Il se passe en fait deux choses à l'exécution de cette commande. En premier lieu, Go télécharge le code source, puis il exécute `go install`. Avant d'utiliser cette commande, assurez-vous d'installer les outils nécessaires. BitBucket (Mercurial Git) - Github (git) + GitHub (git) Google Code (Git, Mercurial, Subversion) Launchpad (Bazaar) diff --git a/ja/01.2.md b/ja/01.2.md index a327a8fe..0a20a02d 100644 --- a/ja/01.2.md +++ b/ja/01.2.md @@ -1,176 +1,176 @@ -# 1.2 GOPATHとワーキングディレクトリ - -さきほどGoをインストールする際はGOPATH変数を設定する必要があるとご説明しました。Goはバージョン1.1から必ずこの変数を設定するようになっており、Goのインストールディレクトリと同じにはできません。このディレクトリは、GoのソースコードやGoの実行可能ファイル、並びにコンパイル済みのパッケージファイルを保存する為に使用します。そのためこのディレクトリには3つのサブディレクトリが存在します:src、bin、pkgです。 - -## GOPATH設定 - go コマンドは、ある重要な環境変数に依存しています:$GOPATH1 - - Windowsシステムにおいて環境変数の形式は`%GOPATH%`です。この本の中では主にUnix形式を使用します。Windowsユーザは適時置き換えてください。 - - *(注:これはGoのインストールディレクトリではありません。以下では筆者のワーキングディレクトリで説明します。もし異なるディレクトリを使用する場合はGOPATHをあなたのワーキングディレクトリに置き換えてください。)* - - Unix に似た環境であれば大体以下のような設定になります: -```sh -export GOPATH=/home/apple/mygo -``` - 上のディレクトリを新たに作成し、上の一行を`.bashrc`または`.zshrc`もしくは自分の`sh`の設定ファイルに加えます。 - - Windows では以下のように設定します。新しくGOPATHと呼ばれる環境変数を作成します: -```sh - GOPATH=c:\mygo -``` -GOPATHは複数のディレクトリを許容します。複数のディレクトリがある場合、デリミタに気をつけてください。複数のディレクトリがある場合Windowsはセミコロン、Linuxはコロンを使います。複数のGOPATHがある場合は、デフォルトでgo getの内容が第一ディレクトリとされます。 - - -上の $GOPATH ディレクトリには3つのディレクトリがあります: - -- src にはソースコードを保存します(例えば:.go .c .h .s等) -- pkg にはコンパイル後に生成されるファイル(例えば:.a) -- bin にはコンパイル後に生成される実行可能ファイル(このまま $PATH 変数に加えてもかまいません。もしいくつもgopathがある場合は、`${GOPATH//://bin:}/bin`を使って全てのbinディレクトリを追加してください) - -以降私はすべての例でmygoを私のgopathディレクトリとします。 - -## ソースコードディレクトリ構成 -GOPATH内のsrcディレクトリはこれから開発するプログラムにとってメインとなるディレクトリです。全てのソースコードはこのディレクトリに置くことになります。一般的な方法では一つのプロジェクトが一つのディレクトリが割り当てられます、例えば:$GOPATH/src/mymath はmymathというアプリケーションパッケージか実行アプリケーションになります。これはpackageがmainかそうでないかによって決定します。mainであれば実行可能アプリケーションで、そうでなければアプリケーションパッケージになります。これに関してはpackageを後ほどご紹介する予定です。 - - -新しくアプリケーションやソースパッケージを作成するときは、srcディレクトリの中にディレクトリを作るところから始めます。ディレクトリ名は一般的にソースパッケージ名になります。もちろんネストしたディレクトリも可能です。例えばsrcの中に$GOPATH/src/github.com/astaxie/beedbというディレクトリを作ったとすると、このパッケージパスは"github.com/astaxie/beedb"になり、パッケージ名は最後のディレクトリであるbeedbになります。 - -以下ではmymathを例にどのようにアプリケーションパッケージをコーディングするかご説明します。以下のコードを実行します。 -```sh -cd $GOPATH/src -mkdir mymath -``` -sqrt.goというファイルを作成し、内容を以下のようにします。 -```go -// $GOPATH/src/mymath/sqrt.goコードは以下の通り: -package mymath - -func Sqrt(x float64) float64 { - z := 0.0 - for i := 0; i < 1000; i++ { - z -= (z*z - x) / (2 * x) - } - return z -} -``` -このように私のアプリケーションパッケージディレクトリとコードが作成されました。注意:一般的にpackageの名前とディレクトリ名は一致させるべきです。 - -## コンパイルアプリケーション -上のとおり、我々はすでに自分のアプリケーションパッケージを作成しましたが、どのようにコンパイル/インストールすべきでしょうか?2種類の方法が存在します。 - -1、対応するアプリケーションパッケージディレクトリに入り、`go install`を実行すればインストールできます。 - -2,任意のディレクトリで以下のコード`go install mymath`を実行します。 - -インストールが終われば、以下のディレクトリに入り -```sh -cd $GOPATH/pkg/${GOOS}_${GOARCH} -//以下のファイルが現れるはずです。 -mymath.a -``` -この.aファイルはアプリケーションパッケージです。ならば我々はどのように実行できるでしょうか? - -次にアプリケーション・プログラムを作成してこのアプリケーションパッケージをコールします。 - -アプリケーションパッケージmathappを作ります。 -```sh -cd $GOPATH/src -mkdir mathapp -cd mathapp -vim main.go -``` - -`$GOPATH/src/mathapp/main.go`コード: -```go -package main - -import ( - "mymath" - "fmt" -) - -func main() { - fmt.Printf("Hello, world. Sqrt(2) = %v\n", mymath.Sqrt(2)) -} -``` -このパッケージは`main`であることが分かると思います。importにおいてコールするパッケージは`mymath`であり、これが`$GOPATH/src`のパスに対応します。もしネストしたディレクトリであれば、importの中でネストしたディレクトリをインポートします。例えばいくつものGOPATHがあった場合も同じで、Goは自動的に複数の`$GOPATH/src`の中から探し出します。 - -さて、どのようにプログラムをコンパイルするのでしょうか?このアプリケーションディレクトリに入り、`go build`を実行すれば、このディレクトリの下にmathappの実行可能ファイルが生成されます。 -```sh -./mathapp -``` - -以下のように出力されます。 -```sh -Hello, world. Sqrt(2) = 1.414213562373095 -``` - -どのようにアプリケーションをインストールするのでしょうか。このディレクトリに入り、`go install`を実行すると、$GOPATH/bin/の下に実行可能ファイルmathappが作成されます。`$GOPATH/bin`が我々のPATHに追加されていることを思い出して下さい、コマンドラインから以下のように入力することで実行することができます。 - -```sh -mathapp -``` - -この場合も以下のように出力されます。 - - Hello, world. Sqrt(2) = 1.414213562373095 - -ここではどのように実行可能アプリケーションをコンパイル/インストールし、ディレクトリ構造を設計するかについてご紹介しました。 - -## リモートパッケージの取得 - go言語はリモートパッケージを取得するツール`go get`を持っています。現在go getは多数のオープンソースリポジトリをサポートしています(github、googlecode、bitbucket、Launchpad) - - go get github.com/astaxie/beedb - ->go get -u オプションはパッケージの自動更新を行います。また、go get時に自動的に当該のパッケージの依存する他のサードパーティパッケージを取得します。 - -このコマンドでふさわしいコードを取得し、対応するオープンソースプラットホームに対し異なるソースコントロールツールを利用します。例えばgithubではgit、googlecodeではhg。そのためこれらのコードを取得したい場合は、先に対応するソースコードコントロールツールをインストールしておく必要があります。 - -上述の方法で取得したコードはローカルの以下の場所に配置されます。 - - $GOPATH - src - |--github.com - |-astaxie - |-beedb - pkg - |--対応プラットフォーム - |-github.com - |--astaxie - |beedb.a - -go getは以下のような手順を踏みます。まずはじめにソースコードツールでコードをsrcの下にcloneします。その後`go install`を実行します。 - -コードの中でリモートパッケージが使用される場合、単純にローカルのパッケージと同じように頭のimportに対応するパスを添えるだけです。 - - import "github.com/astaxie/beedb" - -## プログラムの全体構成 -上記で作成したローカルのmygoのディレクトリ構造は以下のようになっています。 - - bin/ - mathapp - pkg/ - プラットフォーム名/ 例:darwin_amd64、linux_amd64 - mymath.a - github.com/ - astaxie/ - beedb.a - src/ - mathapp - main.go - mymath/ - sqrt.go - github.com/ - astaxie/ - beedb/ - beedb.go - util.go - -上述の構成から明確に判断できるのは、binディレクトリの下にコンパイル後の実行可能ファイルが保存され、pkgの下に関数パッケージが保存され、srcの下にアプリケーションのソースコードが保存されているということです。 - -## links - * [目次]() - * 前へ: [GOのインストール](<01.1.md>) - * 次へ: [GOのコマンド](<01.3.md>) +# 1.2 GOPATHとワーキングディレクトリ + +さきほどGoをインストールする際はGOPATH変数を設定する必要があるとご説明しました。Goはバージョン1.1から必ずこの変数を設定するようになっており、Goのインストールディレクトリと同じにはできません。このディレクトリは、GoのソースコードやGoの実行可能ファイル、並びにコンパイル済みのパッケージファイルを保存する為に使用します。そのためこのディレクトリには3つのサブディレクトリが存在します:src、bin、pkgです。 + +## GOPATH設定 + go コマンドは、ある重要な環境変数に依存しています:$GOPATH1 + + Windowsシステムにおいて環境変数の形式は`%GOPATH%`です。この本の中では主にUnix形式を使用します。Windowsユーザは適時置き換えてください。 + + *(注:これはGoのインストールディレクトリではありません。以下では筆者のワーキングディレクトリで説明します。もし異なるディレクトリを使用する場合はGOPATHをあなたのワーキングディレクトリに置き換えてください。)* + + Unix に似た環境であれば大体以下のような設定になります: +```sh +export GOPATH=/home/apple/mygo +``` + 上のディレクトリを新たに作成し、上の一行を`.bashrc`または`.zshrc`もしくは自分の`sh`の設定ファイルに加えます。 + + Windows では以下のように設定します。新しくGOPATHと呼ばれる環境変数を作成します: +```sh + GOPATH=c:\mygo +``` +GOPATHは複数のディレクトリを許容します。複数のディレクトリがある場合、デリミタに気をつけてください。複数のディレクトリがある場合Windowsはセミコロン、Linuxはコロンを使います。複数のGOPATHがある場合は、デフォルトでgo getの内容が第一ディレクトリとされます。 + + +上の $GOPATH ディレクトリには3つのディレクトリがあります: + +- src にはソースコードを保存します(例えば:.go .c .h .s等) +- pkg にはコンパイル後に生成されるファイル(例えば:.a) +- bin にはコンパイル後に生成される実行可能ファイル(このまま $PATH 変数に加えてもかまいません。もしいくつもgopathがある場合は、`${GOPATH//://bin:}/bin`を使って全てのbinディレクトリを追加してください) + +以降私はすべての例でmygoを私のgopathディレクトリとします。 + +## ソースコードディレクトリ構成 +GOPATH内のsrcディレクトリはこれから開発するプログラムにとってメインとなるディレクトリです。全てのソースコードはこのディレクトリに置くことになります。一般的な方法では一つのプロジェクトが一つのディレクトリが割り当てられます、例えば:$GOPATH/src/mymath はmymathというアプリケーションパッケージか実行アプリケーションになります。これはpackageがmainかそうでないかによって決定します。mainであれば実行可能アプリケーションで、そうでなければアプリケーションパッケージになります。これに関してはpackageを後ほどご紹介する予定です。 + + +新しくアプリケーションやソースパッケージを作成するときは、srcディレクトリの中にディレクトリを作るところから始めます。ディレクトリ名は一般的にソースパッケージ名になります。もちろんネストしたディレクトリも可能です。例えばsrcの中に$GOPATH/src/github.com/astaxie/beedbというディレクトリを作ったとすると、このパッケージパスは"github.com/astaxie/beedb"になり、パッケージ名は最後のディレクトリであるbeedbになります。 + +以下ではmymathを例にどのようにアプリケーションパッケージをコーディングするかご説明します。以下のコードを実行します。 +```sh +cd $GOPATH/src +mkdir mymath +``` +sqrt.goというファイルを作成し、内容を以下のようにします。 +```go +// $GOPATH/src/mymath/sqrt.goコードは以下の通り: +package mymath + +func Sqrt(x float64) float64 { + z := 0.0 + for i := 0; i < 1000; i++ { + z -= (z*z - x) / (2 * x) + } + return z +} +``` +このように私のアプリケーションパッケージディレクトリとコードが作成されました。注意:一般的にpackageの名前とディレクトリ名は一致させるべきです。 + +## コンパイルアプリケーション +上のとおり、我々はすでに自分のアプリケーションパッケージを作成しましたが、どのようにコンパイル/インストールすべきでしょうか?2種類の方法が存在します。 + +1、対応するアプリケーションパッケージディレクトリに入り、`go install`を実行すればインストールできます。 + +2,任意のディレクトリで以下のコード`go install mymath`を実行します。 + +インストールが終われば、以下のディレクトリに入り +```sh +cd $GOPATH/pkg/${GOOS}_${GOARCH} +//以下のファイルが現れるはずです。 +mymath.a +``` +この.aファイルはアプリケーションパッケージです。ならば我々はどのように実行できるでしょうか? + +次にアプリケーション・プログラムを作成してこのアプリケーションパッケージをコールします。 + +アプリケーションパッケージmathappを作ります。 +```sh +cd $GOPATH/src +mkdir mathapp +cd mathapp +vim main.go +``` + +`$GOPATH/src/mathapp/main.go`コード: +```go +package main + +import ( + "mymath" + "fmt" +) + +func main() { + fmt.Printf("Hello, world. Sqrt(2) = %v\n", mymath.Sqrt(2)) +} +``` +このパッケージは`main`であることが分かると思います。importにおいてコールするパッケージは`mymath`であり、これが`$GOPATH/src`のパスに対応します。もしネストしたディレクトリであれば、importの中でネストしたディレクトリをインポートします。例えばいくつものGOPATHがあった場合も同じで、Goは自動的に複数の`$GOPATH/src`の中から探し出します。 + +さて、どのようにプログラムをコンパイルするのでしょうか?このアプリケーションディレクトリに入り、`go build`を実行すれば、このディレクトリの下にmathappの実行可能ファイルが生成されます。 +```sh +./mathapp +``` + +以下のように出力されます。 +```sh +Hello, world. Sqrt(2) = 1.414213562373095 +``` + +どのようにアプリケーションをインストールするのでしょうか。このディレクトリに入り、`go install`を実行すると、$GOPATH/bin/の下に実行可能ファイルmathappが作成されます。`$GOPATH/bin`が我々のPATHに追加されていることを思い出して下さい、コマンドラインから以下のように入力することで実行することができます。 + +```sh +mathapp +``` + +この場合も以下のように出力されます。 + + Hello, world. Sqrt(2) = 1.414213562373095 + +ここではどのように実行可能アプリケーションをコンパイル/インストールし、ディレクトリ構造を設計するかについてご紹介しました。 + +## リモートパッケージの取得 + go言語はリモートパッケージを取得するツール`go get`を持っています。現在go getは多数のオープンソースリポジトリをサポートしています(GitHub、googlecode、bitbucket、Launchpad) + + go get github.com/astaxie/beedb + +>go get -u オプションはパッケージの自動更新を行います。また、go get時に自動的に当該のパッケージの依存する他のサードパーティパッケージを取得します。 + +このコマンドでふさわしいコードを取得し、対応するオープンソースプラットホームに対し異なるソースコントロールツールを利用します。例えばGitHubではgit、googlecodeではhg。そのためこれらのコードを取得したい場合は、先に対応するソースコードコントロールツールをインストールしておく必要があります。 + +上述の方法で取得したコードはローカルの以下の場所に配置されます。 + + $GOPATH + src + |--github.com + |-astaxie + |-beedb + pkg + |--対応プラットフォーム + |-github.com + |--astaxie + |beedb.a + +go getは以下のような手順を踏みます。まずはじめにソースコードツールでコードをsrcの下にcloneします。その後`go install`を実行します。 + +コードの中でリモートパッケージが使用される場合、単純にローカルのパッケージと同じように頭のimportに対応するパスを添えるだけです。 + + import "github.com/astaxie/beedb" + +## プログラムの全体構成 +上記で作成したローカルのmygoのディレクトリ構造は以下のようになっています。 + + bin/ + mathapp + pkg/ + プラットフォーム名/ 例:darwin_amd64、linux_amd64 + mymath.a + github.com/ + astaxie/ + beedb.a + src/ + mathapp + main.go + mymath/ + sqrt.go + github.com/ + astaxie/ + beedb/ + beedb.go + util.go + +上述の構成から明確に判断できるのは、binディレクトリの下にコンパイル後の実行可能ファイルが保存され、pkgの下に関数パッケージが保存され、srcの下にアプリケーションのソースコードが保存されているということです。 + +## links + * [目次]() + * 前へ: [GOのインストール](<01.1.md>) + * 次へ: [GOのコマンド](<01.3.md>) diff --git a/ja/01.4.md b/ja/01.4.md index a1776220..ae9ee336 100644 --- a/ja/01.4.md +++ b/ja/01.4.md @@ -1,430 +1,430 @@ -# 1.4 Go開発ツール - -本章ではいくつかの開発ツールをご紹介します。これらはすべて自動化を備えており、fmt機能を自動化します。なぜならこれらはすべてクロスプラットフォームであり、そのためインストール手順といったものはすべて同じものです。 - -## LiteIDE - - LiteIDEはGo言語の開発に特化したクロスプラットフォームの軽量統合開発環境(IDE)です。visualfcで書かれています。 - - ![](images/1.4.liteide.png?raw=true) - -図1.4 LiteIDEのメイン画面 - -**LiteIDEの主な特徴:** - -* 主なオペレーティングシステムのサポート - * Windows - * Linux - * MacOS X -* Goコンパイル環境の管理と切り替え - * 複数のGoコンパイル環境の管理と切り替え - * Go言語のクロスコンパイルのサポート -* Go標準と同じ項目管理方式 - * GOPATHに基づいたパッケージブラウザ - * GOPATHに基づいたコンパイルシステム - * GOPATHに基づいたドキュメント検索 -* Go言語の編集サポート - * クラスブラウザとアウトライン表示 - * Gocode(コード自動作成ツール)の完全なサポート - * Go言語ドキュメントとApi高速検索 - * コード表現情報の表示`F1` - * ソースコード定義とジャンプのサポート`F2` - * Gdbブレークポイントとテストサポート - * gofmt自動整形のサポート -* その他の特徴 - * 多言語メニューのサポート - * 完全にプラガブルな構成 - * エディタのカラーリングサポート - * Kateに基づいた文法表示サポート - * 全文に基づく単語の自動補完 - * キーボードショートカットのバインディングサポート - * Markdownドキュメントの編集サポート - * リアルタイムプレビューと表示の同期 - * カスタムCSS表示 - * HTML及びPDFドキュメントのエクスポート - * HTML/PDFドキュメントへの変換とマージ - -**LiteIDEインストール設定** - -* LiteIDEインストール - * ダウンロード http://sourceforge.net/projects/liteide/files/> - * ソースコード - - まずGo言語環境をインストールし、その後オペレーティングシステムにしたがってLiteIDEの対応圧縮ファイルを直接解凍すれば使用できます。 - -* コンパイル環境設定 - - 自身のシステムの要求にしたがってLiteIDEが現在使用している環境変数を切り替えまたは設定します。 - - Windowsオペレーティングシステムの64bitGo言語の場合、 - ツール欄の環境設定のなかでwin64を選択し、`編集環境`をクリックしてLiteIDEからwin64.envファイルを編集します。 - - GOROOT=c:\go - GOBIN= - GOARCH=amd64 - GOOS=windows - CGO_ENABLED=1 - - PATH=%GOBIN%;%GOROOT%\bin;%PATH% - 。。。 - - この中の`GOROOT=c:\go`を現在のGoのインストールパスに修正し、保存するだけです。もしMinGW64があれば、`c:\MinGW64\bin`をPATHの中に入れて、goによるgccのコールでCGOコンパイラのサポートを利用することができます。 - - Linuxオペレーティングシステムで64bitGo言語の場合、 - ツール欄の環境設定の中からlinux64を選び、`編集環境`をクリックし、LiteIDEからlinux64.envファイルを編集します。 - - GOROOT=$HOME/go - GOBIN= - GOARCH=amd64 - GOOS=linux - CGO_ENABLED=1 - - PATH=$GOBIN:$GOROOT/bin:$PATH - 。。。 - - この中の`GOROOT=$HOME/go`を現在のGoのインストールパスに修正して保存します。 - -* GOPATH設定 - - Go言語のツールキーはGOPATH設定を使用します。Go言語開発のプロジェクトのパスリストです。コマンドライン(LiteIDEでは`Ctrl+,`を直接入力できます)で`go help gopath`を入力するとGOPATHドキュメントを素早く確認できます。 - - LiteIDEでは簡単に確認でき、GOPATHを設定することができます。`メニュー-確認-GOPATH`設定を通じて、システム中に存在するGOPATHリストを確認することができます。 - 同時に必要な追加項目にそってカスタムのGOPATHリストに追加することができます。 - -## Sublime Text - - ここではSublime Text 2(以下「Sublime」)+GoSublimeの組み合わせをご紹介します。なぜこの組み合わせなのでしょうか? - - - コード表示の自動化、以下の図の通り - - ![](images/1.4.sublime1.png?raw=true) - - 図1.5 sublimeコードの自動化画面 - - - 保存した時にはコードが自動的に整形されています。あなたの書いたコードをより美しくGoの標準に合うよう仕上げてくれます。 - - プロジェクト管理のサポート - - ![](images/1.4.sublime2.png?raw=true) - - 図1.6 sublimeプロジェクト管理画面  - - - 文法のハイライトサポート - - Sublime Text 2はフリーで使用できます。保存回数が一定の量を超えると購入するかのダイアログが現れるので、継続利用をキャンセルするをクリックします。正式登録版とは何の違いもありません。 - - -次はどのようにインストールするかご説明します。[Sublime](http://www.sublimetext.com/)ダウンロードします。 - - 自分のシステムに合わせて対応するバージョンをダウンロードし、Sublimeを開きます。Sublimeに詳しくない方はまず[Sublime Text 2 入門とテクニック](http://lucifr.com/139225/sublime-text-2-tricks-and-tips/)の文章を読んでみてください。 - - 1. 開いた後、 Package Controlをインストールします。Ctrl+`でコマンドラインを開き、以下のコードを実行します: - - import urllib2,os; pf='Package Control.sublime-package'; ipp=sublime.installed_packages_path(); os.makedirs(ipp) if not os.path.exists(ipp) else None; urllib2.install_opener(urllib2.build_opener(urllib2.ProxyHandler())); open(os.path.join(ipp,pf),'wb').write(urllib2.urlopen('http://sublime.wbond.net/'+pf.replace(' ','%20')).read()); print 'Please restart Sublime Text to finish installation' - - この時Sublimeを再度開き直してください。メニュー欄に一つ項目が増えているのがお分かりいただけるかと思います。これでPackage Controlが正しくインストールされました。 - - ![](images/1.4.sublime3.png?raw=true) - - 図1.7 sublimeパッケージ管理 - - - 2. インストールが完了するとSublimeのプラグインをインストールできます。GoSublime, SidebarEnhancementsとGo Buildをインストールする必要があるので、プラグインをインストールしたあとSublimeを再起動させて有効にしてください。Ctrl+Shift+pでPackage Controlを開き、`pcip`を入力します。(これは"Package Control: Install Package"と省略されます)。 - - この時、左下のコーナーに現在読み込んでいるパッケージデータが表示されます。完了すると下のような画面になります。 - - ![](images/1.4.sublime4.png?raw=true) - - 図1.8 sublimeプラグインのインストール画面 - - この時、GoSublimeと入力し、「確認」をクリックするとインストールが始まります。同じようにSidebarEnhancementsとGo Buildにも行います。 - - 3. インストールが成功したかテストします。Sublimeを開き、main.goを開いて文法がハイライトされているのをご確認ください。`import`を入力してコードの自動表示がされます。`import "fmt"`のあとに`fmt.`を入力すると自動的に関数の候補が現れます。 - - もしすでにこのような表示がされる場合は、インストールが成功しており、自動補完が完了しています。 - - もしこのような表示がなされない場合、あなたの`$PATH`が正しく設定されていないのかもしれません。ターミナルを開き、gocodeを入力して、正しく実行できるか確認してください。もしダメであれば`$PATH`が正しく設定されていません。 - (XP向け)たまたまターミナルでの実行が成功することもあります。しかしsublimeは何も知らせてくれないかデコードエラーが発生します。sublime text3とconvert utf8プラグインを試してみてください。 - - 4. MacOSではすでに$GOROOT, $GOPATH, $GOBINが設定されていても自動的にはどうすればよいか教えてくれません。 - - sublimeにてcommand + 9を押し、envを入力して$PATH, $GOROOT, $GOPATH, $GOBINといった変数を確認します。もしなければ、以下の手順に従ってください。 - - まず下のシンボリックリンクを作成し、Terminalで直接sublimeを起動します - - ln -s /Applications/Sublime\ Text\ 2.app/Contents/SharedSupport/bin/subl /usr/local/bin/sublime - - -## Vim -Vimはviから発展したテキストエディタです。コード補完、コンパイルまたエラージャンプなど、プログラミングに特化した機能が豊富です。広くプログラマに使用されています。 - -![](images/1.4.vim.png?raw=true) - -図1.9 VIMエディタのGoの自動補完画面 - - 1. vimハイライト表示の設定 - - cp -r $GOROOT/misc/vim/* ~/.vim/ - - 2. ~/.vimrcファイルで文法のハイライト表示を追加します - - filetype plugin indent on - syntax on - - 3. [Gocode](https://github.com/nsf/gocode/)をインストールします - - go get -u github.com/nsf/gocode - - gocodeはデフォルトで`$GOPATH/bin`の下にインストールされています。 - - 4. [Gocode](https://github.com/nsf/gocode/)を設定します。 - - ~ cd $GOPATH/src/github.com/nsf/gocode/vim - ~ ./update.bash - ~ gocode set propose-builtins true - propose-builtins true - ~ gocode set lib-path "/home/border/gocode/pkg/linux_amd64" - lib-path "/home/border/gocode/pkg/linux_amd64" - ~ gocode set - propose-builtins true - lib-path "/home/border/gocode/pkg/linux_amd64" - - >gocode setの2つのパラメータの意味を説明します: - > - >propose-builtins:はGoのビルトイン関数を補完するかです。タイプは定数です。デフォルトはfalseで、表示しません。 - > - >lib-path:デフォルトで、gocodeは**$GOPATH/pkg/$GOOS_$GOARCH**と**$GOROOT/pkg/$GOOS_$GOARCH**ディレクトリのパッケージを検索するだけです。当然この設定には私達の外側のlibを検索できるようパスを設定することができます。 - - - 5. おめでとうございます。インストール完了です。あなたは今から`:e main.go`でGoで開発する面白さを体験することができます。 - -より多くのVIMの設定は、[リンク](http://monnand.me/p/vim-golang-environment/zhCN/)をご参照ください。 - -## Emacs -Emacsは伝説の神器です。彼女はエディタであるだけでなく、統合環境でもあります。または開発環境の集大成と呼んでもよいかもしれません。これらの機能はユーザの身を万能のオペレーティングシステムに置きます。 - - ![](images/1.4.emacs.png?raw=true) - -図1.10 EmacsでGoを編集するメイン画面 - -1. Emacsのハイライト表示設定 - - cp $GOROOT/misc/emacs/* ~/.emacs.d/ - -2. [Gocode](https://github.com/nsf/gocode/)をインストール - - go get -u github.com/nsf/gocode - - gocodeはデフォルトで`$GOBIN`の下にインストールされます。 - -3. [Gocode](https://github.com/nsf/gocode/)を設定 - - - ~ cd $GOPATH/src/github.com/nsf/gocode/emacs - ~ cp go-autocomplete.el ~/.emacs.d/ - ~ gocode set propose-builtins true - propose-builtins true - ~ gocode set lib-path "/home/border/gocode/pkg/linux_amd64" // あなたのパスに置き換えてください。 - lib-path "/home/border/gocode/pkg/linux_amd64" - ~ gocode set - propose-builtins true - lib-path "/home/border/gocode/pkg/linux_amd64" - -4. [Auto Completion](http://www.emacswiki.org/emacs/AutoComplete)をインストールする必要があります。 - - AutoCompleteをダウンロードして解凍します。 - - ~ make install DIR=$HOME/.emacs.d/auto-complete - - ~/.emacsファイルを設定します。 - - ;;auto-complete - (require 'auto-complete-config) - (add-to-list 'ac-dictionary-directories "~/.emacs.d/auto-complete/ac-dict") - (ac-config-default) - (local-set-key (kbd "M-/") 'semantic-complete-analyze-inline) - (local-set-key "." 'semantic-complete-self-insert) - (local-set-key ">" 'semantic-complete-self-insert) - - 詳細情報はこちらを参考にしてください:http://www.emacswiki.org/emacs/AutoComplete - -5. .emacsを設定します。 - - ;; golang mode - (require 'go-mode-load) - (require 'go-autocomplete) - ;; speedbar - ;; (speedbar 1) - (speedbar-add-supported-extension ".go") - (add-hook - 'go-mode-hook - '(lambda () - ;; gocode - (auto-complete-mode 1) - (setq ac-sources '(ac-source-go)) - ;; Imenu & Speedbar - (setq imenu-generic-expression - '(("type" "^type *\\([^ \t\n\r\f]*\\)" 1) - ("func" "^func *\\(.*\\) {" 1))) - (imenu-add-to-menubar "Index") - ;; Outline mode - (make-local-variable 'outline-regexp) - (setq outline-regexp "//\\.\\|//[^\r\n\f][^\r\n\f]\\|pack\\|func\\|impo\\|cons\\|var.\\|type\\|\t\t*....") - (outline-minor-mode 1) - (local-set-key "\M-a" 'outline-previous-visible-heading) - (local-set-key "\M-e" 'outline-next-visible-heading) - ;; Menu bar - (require 'easymenu) - (defconst go-hooked-menu - '("Go tools" - ["Go run buffer" go t] - ["Go reformat buffer" go-fmt-buffer t] - ["Go check buffer" go-fix-buffer t])) - (easy-menu-define - go-added-menu - (current-local-map) - "Go tools" - go-hooked-menu) - - ;; Other - (setq show-trailing-whitespace t) - )) - ;; helper function - (defun go () - "run current buffer" - (interactive) - (compile (concat "go run " (buffer-file-name)))) - - ;; helper function - (defun go-fmt-buffer () - "run gofmt on current buffer" - (interactive) - (if buffer-read-only - (progn - (ding) - (message "Buffer is read only")) - (let ((p (line-number-at-pos)) - (filename (buffer-file-name)) - (old-max-mini-window-height max-mini-window-height)) - (show-all) - (if (get-buffer "*Go Reformat Errors*") - (progn - (delete-windows-on "*Go Reformat Errors*") - (kill-buffer "*Go Reformat Errors*"))) - (setq max-mini-window-height 1) - (if (= 0 (shell-command-on-region (point-min) (point-max) "gofmt" "*Go Reformat Output*" nil "*Go Reformat Errors*" t)) - (progn - (erase-buffer) - (insert-buffer-substring "*Go Reformat Output*") - (goto-char (point-min)) - (forward-line (1- p))) - (with-current-buffer "*Go Reformat Errors*" - (progn - (goto-char (point-min)) - (while (re-search-forward "" nil t) - (replace-match filename)) - (goto-char (point-min)) - (compilation-mode)))) - (setq max-mini-window-height old-max-mini-window-height) - (delete-windows-on "*Go Reformat Output*") - (kill-buffer "*Go Reformat Output*")))) - ;; helper function - (defun go-fix-buffer () - "run gofix on current buffer" - (interactive) - (show-all) - (shell-command-on-region (point-min) (point-max) "go tool fix -diff")) - -6. おめでとうございます。今からあなたはこの神器を使ってGo開発の楽しみを体験できます。デフォルトのspeedbarは閉じています。もし開く場合は ;; (speedbar 1) の前のコメントを取り去るか、*M-x speedbar*を手動で起動してください。 - -## Eclipse -Eclipseも非常によく使われる開発ツールです。以下ではEclipseを使ってどのようにGoプログラムを編集するかご紹介します。 - - ![](images/1.4.eclipse1.png?raw=true) - -図1.11 EclipseでのGo編集のメイン画面 - -1. まず[Eclipse](http://www.eclipse.org/)をダウンロードしてインストールします。 - -2. [goclipse](https://code.google.com/p/goclipse/)プラグインをダウンロードします。 - - http://code.google.com/p/goclipse/wiki/InstallationInstructions - -3. gocodeをダウンロードして、goのコード補完を表示させます。 - - gocodeのgithubアドレス: - - https://github.com/nsf/gocode - - windowsではgitをインストールする必要があります。通常は[msysgit](https://code.google.com/p/msysgit/)を使います。 - - cmdでインストールを行います: - - go get -u github.com/nsf/gocode - - 以下のコードをダウンロードし、直接go buildでコンパイルしてもかまいません。この場合はgocode.exeが生成されます。 - -4. [MinGW](http://sourceforge.net/projects/mingw/files/MinGW/)をダウンロードして要求に従いインストールしてください。 - -5. プラグイン設定 - - Windows->Reference->Go - - (1).Goのコンパイラを設定します。 - - ![](images/1.4.eclipse2.png?raw=true) - - 図1.12 Goの基本情報を設定します。 - - - (2).Gocodeを設定します(オプション、コード補完)、Gocodeのパスは事前に生成したgocode.exeファイルを設定します。 - - ![](images/1.4.eclipse3.png?raw=true) - - 図1.13 gocode情報を設定します。 - - (3).GDBを設定します(オプション、テスト用)、GDBのパスはMingGWのインストールディレクトリ下のgdb.exeファイルを設定します。 - - ![](images/1.4.eclipse4.png?raw=true) - - 図1.14 GDB情報の設定 - -6. テストが成功するか - - goプロジェクトを一つ新規作成して、hello.goを作成します: - - ![](images/1.4.eclipse5.png?raw=true) - - 図1.15 プロジェクトの新規作成とファイルの編集 - - テストの実行(consoleでコマンドを入力する必要があります): - - ![](images/1.4.eclipse6.png?raw=true) - - 図1.16 Goプログラムのテスト - -## IntelliJ IDEA -Javaに親しい読者はideaに詳しいことでしょう。ideaはプラグインを通してgo言語のシンタックスハイライト、コード補完およびリビルドをサポートしています。 - -1. ideaを先にダウンロードします。ideaはマルチプラットフォームをサポートしています:win,mac,linux、もしお金があれば正式版を購入します、もし無ければ、コミュニティの無料版を使ってください。Go言語を開発するだけであれば無料版で十分事足ります。 - - ![](images/1.4.idea1.png?raw=true) - -2. Goプラグインをインストールし、FileメニューのSettingをクリックします。Pluginsを探したら、Browser repoボタンをクリックします。中国国内のユーザはおそらくエラーが出るかもしれませんが、自分で解決してくれよな。 - - ![](images/1.4.idea3.png?raw=true) - -3. この時いくつものプラグインが見つかります。Golangを検索して、download and installをダブルクリックしてください。golangの行末にDownloadedの表示が現れるのを待って、OKをクリックします。 - - ![](images/1.4.idea4.png?raw=true) - - その後Applyをクリックすると、IDEが再起動を要求します。 - -4. 再起動が完了し、新規プロジェクトを作成すると、golangプロジェクトが作成可能であることがお分かりいただけるかとおもいます: - - ![](images/1.4.idea5.png?raw=true) - - 次に、go sdkの場所を入力するよう促されるかもしれません。普段はいつもC:\Goにインストールされています。Linuxとmacは自分のインストールディレクトリの設定にしたがって、ディレクトリを選択すれば大丈夫です。 - -## links - * [目次]() - * 前へ: [Goのコマンド](<01.3.md>) - * 次へ: [まとめ](<01.5.md>) +# 1.4 Go開発ツール + +本章ではいくつかの開発ツールをご紹介します。これらはすべて自動化を備えており、fmt機能を自動化します。なぜならこれらはすべてクロスプラットフォームであり、そのためインストール手順といったものはすべて同じものです。 + +## LiteIDE + + LiteIDEはGo言語の開発に特化したクロスプラットフォームの軽量統合開発環境(IDE)です。visualfcで書かれています。 + + ![](images/1.4.liteide.png?raw=true) + +図1.4 LiteIDEのメイン画面 + +**LiteIDEの主な特徴:** + +* 主なオペレーティングシステムのサポート + * Windows + * Linux + * MacOS X +* Goコンパイル環境の管理と切り替え + * 複数のGoコンパイル環境の管理と切り替え + * Go言語のクロスコンパイルのサポート +* Go標準と同じ項目管理方式 + * GOPATHに基づいたパッケージブラウザ + * GOPATHに基づいたコンパイルシステム + * GOPATHに基づいたドキュメント検索 +* Go言語の編集サポート + * クラスブラウザとアウトライン表示 + * Gocode(コード自動作成ツール)の完全なサポート + * Go言語ドキュメントとApi高速検索 + * コード表現情報の表示`F1` + * ソースコード定義とジャンプのサポート`F2` + * Gdbブレークポイントとテストサポート + * gofmt自動整形のサポート +* その他の特徴 + * 多言語メニューのサポート + * 完全にプラガブルな構成 + * エディタのカラーリングサポート + * Kateに基づいた文法表示サポート + * 全文に基づく単語の自動補完 + * キーボードショートカットのバインディングサポート + * Markdownドキュメントの編集サポート + * リアルタイムプレビューと表示の同期 + * カスタムCSS表示 + * HTML及びPDFドキュメントのエクスポート + * HTML/PDFドキュメントへの変換とマージ + +**LiteIDEインストール設定** + +* LiteIDEインストール + * ダウンロード http://sourceforge.net/projects/liteide/files/> + * ソースコード + + まずGo言語環境をインストールし、その後オペレーティングシステムにしたがってLiteIDEの対応圧縮ファイルを直接解凍すれば使用できます。 + +* コンパイル環境設定 + + 自身のシステムの要求にしたがってLiteIDEが現在使用している環境変数を切り替えまたは設定します。 + + Windowsオペレーティングシステムの64bitGo言語の場合、 + ツール欄の環境設定のなかでwin64を選択し、`編集環境`をクリックしてLiteIDEからwin64.envファイルを編集します。 + + GOROOT=c:\go + GOBIN= + GOARCH=amd64 + GOOS=windows + CGO_ENABLED=1 + + PATH=%GOBIN%;%GOROOT%\bin;%PATH% + 。。。 + + この中の`GOROOT=c:\go`を現在のGoのインストールパスに修正し、保存するだけです。もしMinGW64があれば、`c:\MinGW64\bin`をPATHの中に入れて、goによるgccのコールでCGOコンパイラのサポートを利用することができます。 + + Linuxオペレーティングシステムで64bitGo言語の場合、 + ツール欄の環境設定の中からlinux64を選び、`編集環境`をクリックし、LiteIDEからlinux64.envファイルを編集します。 + + GOROOT=$HOME/go + GOBIN= + GOARCH=amd64 + GOOS=linux + CGO_ENABLED=1 + + PATH=$GOBIN:$GOROOT/bin:$PATH + 。。。 + + この中の`GOROOT=$HOME/go`を現在のGoのインストールパスに修正して保存します。 + +* GOPATH設定 + + Go言語のツールキーはGOPATH設定を使用します。Go言語開発のプロジェクトのパスリストです。コマンドライン(LiteIDEでは`Ctrl+,`を直接入力できます)で`go help gopath`を入力するとGOPATHドキュメントを素早く確認できます。 + + LiteIDEでは簡単に確認でき、GOPATHを設定することができます。`メニュー-確認-GOPATH`設定を通じて、システム中に存在するGOPATHリストを確認することができます。 + 同時に必要な追加項目にそってカスタムのGOPATHリストに追加することができます。 + +## Sublime Text + + ここではSublime Text 2(以下「Sublime」)+GoSublimeの組み合わせをご紹介します。なぜこの組み合わせなのでしょうか? + + - コード表示の自動化、以下の図の通り + + ![](images/1.4.sublime1.png?raw=true) + + 図1.5 sublimeコードの自動化画面 + + - 保存した時にはコードが自動的に整形されています。あなたの書いたコードをより美しくGoの標準に合うよう仕上げてくれます。 + - プロジェクト管理のサポート + + ![](images/1.4.sublime2.png?raw=true) + + 図1.6 sublimeプロジェクト管理画面  + + - 文法のハイライトサポート + - Sublime Text 2はフリーで使用できます。保存回数が一定の量を超えると購入するかのダイアログが現れるので、継続利用をキャンセルするをクリックします。正式登録版とは何の違いもありません。 + + +次はどのようにインストールするかご説明します。[Sublime](http://www.sublimetext.com/)ダウンロードします。 + + 自分のシステムに合わせて対応するバージョンをダウンロードし、Sublimeを開きます。Sublimeに詳しくない方はまず[Sublime Text 2 入門とテクニック](http://lucifr.com/139225/sublime-text-2-tricks-and-tips/)の文章を読んでみてください。 + + 1. 開いた後、 Package Controlをインストールします。Ctrl+`でコマンドラインを開き、以下のコードを実行します: + + import urllib2,os; pf='Package Control.sublime-package'; ipp=sublime.installed_packages_path(); os.makedirs(ipp) if not os.path.exists(ipp) else None; urllib2.install_opener(urllib2.build_opener(urllib2.ProxyHandler())); open(os.path.join(ipp,pf),'wb').write(urllib2.urlopen('http://sublime.wbond.net/'+pf.replace(' ','%20')).read()); print 'Please restart Sublime Text to finish installation' + + この時Sublimeを再度開き直してください。メニュー欄に一つ項目が増えているのがお分かりいただけるかと思います。これでPackage Controlが正しくインストールされました。 + + ![](images/1.4.sublime3.png?raw=true) + + 図1.7 sublimeパッケージ管理 + + + 2. インストールが完了するとSublimeのプラグインをインストールできます。GoSublime, SidebarEnhancementsとGo Buildをインストールする必要があるので、プラグインをインストールしたあとSublimeを再起動させて有効にしてください。Ctrl+Shift+pでPackage Controlを開き、`pcip`を入力します。(これは"Package Control: Install Package"と省略されます)。 + + この時、左下のコーナーに現在読み込んでいるパッケージデータが表示されます。完了すると下のような画面になります。 + + ![](images/1.4.sublime4.png?raw=true) + + 図1.8 sublimeプラグインのインストール画面 + + この時、GoSublimeと入力し、「確認」をクリックするとインストールが始まります。同じようにSidebarEnhancementsとGo Buildにも行います。 + + 3. インストールが成功したかテストします。Sublimeを開き、main.goを開いて文法がハイライトされているのをご確認ください。`import`を入力してコードの自動表示がされます。`import "fmt"`のあとに`fmt.`を入力すると自動的に関数の候補が現れます。 + + もしすでにこのような表示がされる場合は、インストールが成功しており、自動補完が完了しています。 + + もしこのような表示がなされない場合、あなたの`$PATH`が正しく設定されていないのかもしれません。ターミナルを開き、gocodeを入力して、正しく実行できるか確認してください。もしダメであれば`$PATH`が正しく設定されていません。 + (XP向け)たまたまターミナルでの実行が成功することもあります。しかしsublimeは何も知らせてくれないかデコードエラーが発生します。sublime text3とconvert utf8プラグインを試してみてください。 + + 4. MacOSではすでに$GOROOT, $GOPATH, $GOBINが設定されていても自動的にはどうすればよいか教えてくれません。 + + sublimeにてcommand + 9を押し、envを入力して$PATH, $GOROOT, $GOPATH, $GOBINといった変数を確認します。もしなければ、以下の手順に従ってください。 + + まず下のシンボリックリンクを作成し、Terminalで直接sublimeを起動します + + ln -s /Applications/Sublime\ Text\ 2.app/Contents/SharedSupport/bin/subl /usr/local/bin/sublime + + +## Vim +Vimはviから発展したテキストエディタです。コード補完、コンパイルまたエラージャンプなど、プログラミングに特化した機能が豊富です。広くプログラマに使用されています。 + +![](images/1.4.vim.png?raw=true) + +図1.9 VIMエディタのGoの自動補完画面 + + 1. vimハイライト表示の設定 + + cp -r $GOROOT/misc/vim/* ~/.vim/ + + 2. ~/.vimrcファイルで文法のハイライト表示を追加します + + filetype plugin indent on + syntax on + + 3. [Gocode](https://github.com/nsf/gocode/)をインストールします + + go get -u github.com/nsf/gocode + + gocodeはデフォルトで`$GOPATH/bin`の下にインストールされています。 + + 4. [Gocode](https://github.com/nsf/gocode/)を設定します。 + + ~ cd $GOPATH/src/github.com/nsf/gocode/vim + ~ ./update.bash + ~ gocode set propose-builtins true + propose-builtins true + ~ gocode set lib-path "/home/border/gocode/pkg/linux_amd64" + lib-path "/home/border/gocode/pkg/linux_amd64" + ~ gocode set + propose-builtins true + lib-path "/home/border/gocode/pkg/linux_amd64" + + >gocode setの2つのパラメータの意味を説明します: + > + >propose-builtins:はGoのビルトイン関数を補完するかです。タイプは定数です。デフォルトはfalseで、表示しません。 + > + >lib-path:デフォルトで、gocodeは**$GOPATH/pkg/$GOOS_$GOARCH**と**$GOROOT/pkg/$GOOS_$GOARCH**ディレクトリのパッケージを検索するだけです。当然この設定には私達の外側のlibを検索できるようパスを設定することができます。 + + + 5. おめでとうございます。インストール完了です。あなたは今から`:e main.go`でGoで開発する面白さを体験することができます。 + +より多くのVIMの設定は、[リンク](http://monnand.me/p/vim-golang-environment/zhCN/)をご参照ください。 + +## Emacs +Emacsは伝説の神器です。彼女はエディタであるだけでなく、統合環境でもあります。または開発環境の集大成と呼んでもよいかもしれません。これらの機能はユーザの身を万能のオペレーティングシステムに置きます。 + + ![](images/1.4.emacs.png?raw=true) + +図1.10 EmacsでGoを編集するメイン画面 + +1. Emacsのハイライト表示設定 + + cp $GOROOT/misc/emacs/* ~/.emacs.d/ + +2. [Gocode](https://github.com/nsf/gocode/)をインストール + + go get -u github.com/nsf/gocode + + gocodeはデフォルトで`$GOBIN`の下にインストールされます。 + +3. [Gocode](https://github.com/nsf/gocode/)を設定 + + + ~ cd $GOPATH/src/github.com/nsf/gocode/emacs + ~ cp go-autocomplete.el ~/.emacs.d/ + ~ gocode set propose-builtins true + propose-builtins true + ~ gocode set lib-path "/home/border/gocode/pkg/linux_amd64" // あなたのパスに置き換えてください。 + lib-path "/home/border/gocode/pkg/linux_amd64" + ~ gocode set + propose-builtins true + lib-path "/home/border/gocode/pkg/linux_amd64" + +4. [Auto Completion](http://www.emacswiki.org/emacs/AutoComplete)をインストールする必要があります。 + + AutoCompleteをダウンロードして解凍します。 + + ~ make install DIR=$HOME/.emacs.d/auto-complete + + ~/.emacsファイルを設定します。 + + ;;auto-complete + (require 'auto-complete-config) + (add-to-list 'ac-dictionary-directories "~/.emacs.d/auto-complete/ac-dict") + (ac-config-default) + (local-set-key (kbd "M-/") 'semantic-complete-analyze-inline) + (local-set-key "." 'semantic-complete-self-insert) + (local-set-key ">" 'semantic-complete-self-insert) + + 詳細情報はこちらを参考にしてください:http://www.emacswiki.org/emacs/AutoComplete + +5. .emacsを設定します。 + + ;; golang mode + (require 'go-mode-load) + (require 'go-autocomplete) + ;; speedbar + ;; (speedbar 1) + (speedbar-add-supported-extension ".go") + (add-hook + 'go-mode-hook + '(lambda () + ;; gocode + (auto-complete-mode 1) + (setq ac-sources '(ac-source-go)) + ;; Imenu & Speedbar + (setq imenu-generic-expression + '(("type" "^type *\\([^ \t\n\r\f]*\\)" 1) + ("func" "^func *\\(.*\\) {" 1))) + (imenu-add-to-menubar "Index") + ;; Outline mode + (make-local-variable 'outline-regexp) + (setq outline-regexp "//\\.\\|//[^\r\n\f][^\r\n\f]\\|pack\\|func\\|impo\\|cons\\|var.\\|type\\|\t\t*....") + (outline-minor-mode 1) + (local-set-key "\M-a" 'outline-previous-visible-heading) + (local-set-key "\M-e" 'outline-next-visible-heading) + ;; Menu bar + (require 'easymenu) + (defconst go-hooked-menu + '("Go tools" + ["Go run buffer" go t] + ["Go reformat buffer" go-fmt-buffer t] + ["Go check buffer" go-fix-buffer t])) + (easy-menu-define + go-added-menu + (current-local-map) + "Go tools" + go-hooked-menu) + + ;; Other + (setq show-trailing-whitespace t) + )) + ;; helper function + (defun go () + "run current buffer" + (interactive) + (compile (concat "go run " (buffer-file-name)))) + + ;; helper function + (defun go-fmt-buffer () + "run gofmt on current buffer" + (interactive) + (if buffer-read-only + (progn + (ding) + (message "Buffer is read only")) + (let ((p (line-number-at-pos)) + (filename (buffer-file-name)) + (old-max-mini-window-height max-mini-window-height)) + (show-all) + (if (get-buffer "*Go Reformat Errors*") + (progn + (delete-windows-on "*Go Reformat Errors*") + (kill-buffer "*Go Reformat Errors*"))) + (setq max-mini-window-height 1) + (if (= 0 (shell-command-on-region (point-min) (point-max) "gofmt" "*Go Reformat Output*" nil "*Go Reformat Errors*" t)) + (progn + (erase-buffer) + (insert-buffer-substring "*Go Reformat Output*") + (goto-char (point-min)) + (forward-line (1- p))) + (with-current-buffer "*Go Reformat Errors*" + (progn + (goto-char (point-min)) + (while (re-search-forward "" nil t) + (replace-match filename)) + (goto-char (point-min)) + (compilation-mode)))) + (setq max-mini-window-height old-max-mini-window-height) + (delete-windows-on "*Go Reformat Output*") + (kill-buffer "*Go Reformat Output*")))) + ;; helper function + (defun go-fix-buffer () + "run gofix on current buffer" + (interactive) + (show-all) + (shell-command-on-region (point-min) (point-max) "go tool fix -diff")) + +6. おめでとうございます。今からあなたはこの神器を使ってGo開発の楽しみを体験できます。デフォルトのspeedbarは閉じています。もし開く場合は ;; (speedbar 1) の前のコメントを取り去るか、*M-x speedbar*を手動で起動してください。 + +## Eclipse +Eclipseも非常によく使われる開発ツールです。以下ではEclipseを使ってどのようにGoプログラムを編集するかご紹介します。 + + ![](images/1.4.eclipse1.png?raw=true) + +図1.11 EclipseでのGo編集のメイン画面 + +1. まず[Eclipse](http://www.eclipse.org/)をダウンロードしてインストールします。 + +2. [goclipse](https://code.google.com/p/goclipse/)プラグインをダウンロードします。 + + http://code.google.com/p/goclipse/wiki/InstallationInstructions + +3. gocodeをダウンロードして、goのコード補完を表示させます。 + + gocodeのGitHubアドレス: + + https://github.com/nsf/gocode + + windowsではgitをインストールする必要があります。通常は[msysgit](https://code.google.com/p/msysgit/)を使います。 + + cmdでインストールを行います: + + go get -u github.com/nsf/gocode + + 以下のコードをダウンロードし、直接go buildでコンパイルしてもかまいません。この場合はgocode.exeが生成されます。 + +4. [MinGW](http://sourceforge.net/projects/mingw/files/MinGW/)をダウンロードして要求に従いインストールしてください。 + +5. プラグイン設定 + + Windows->Reference->Go + + (1).Goのコンパイラを設定します。 + + ![](images/1.4.eclipse2.png?raw=true) + + 図1.12 Goの基本情報を設定します。 + + + (2).Gocodeを設定します(オプション、コード補完)、Gocodeのパスは事前に生成したgocode.exeファイルを設定します。 + + ![](images/1.4.eclipse3.png?raw=true) + + 図1.13 gocode情報を設定します。 + + (3).GDBを設定します(オプション、テスト用)、GDBのパスはMingGWのインストールディレクトリ下のgdb.exeファイルを設定します。 + + ![](images/1.4.eclipse4.png?raw=true) + + 図1.14 GDB情報の設定 + +6. テストが成功するか + + goプロジェクトを一つ新規作成して、hello.goを作成します: + + ![](images/1.4.eclipse5.png?raw=true) + + 図1.15 プロジェクトの新規作成とファイルの編集 + + テストの実行(consoleでコマンドを入力する必要があります): + + ![](images/1.4.eclipse6.png?raw=true) + + 図1.16 Goプログラムのテスト + +## IntelliJ IDEA +Javaに親しい読者はideaに詳しいことでしょう。ideaはプラグインを通してgo言語のシンタックスハイライト、コード補完およびリビルドをサポートしています。 + +1. ideaを先にダウンロードします。ideaはマルチプラットフォームをサポートしています:win,mac,linux、もしお金があれば正式版を購入します、もし無ければ、コミュニティの無料版を使ってください。Go言語を開発するだけであれば無料版で十分事足ります。 + + ![](images/1.4.idea1.png?raw=true) + +2. Goプラグインをインストールし、FileメニューのSettingをクリックします。Pluginsを探したら、Browser repoボタンをクリックします。中国国内のユーザはおそらくエラーが出るかもしれませんが、自分で解決してくれよな。 + + ![](images/1.4.idea3.png?raw=true) + +3. この時いくつものプラグインが見つかります。Golangを検索して、download and installをダブルクリックしてください。golangの行末にDownloadedの表示が現れるのを待って、OKをクリックします。 + + ![](images/1.4.idea4.png?raw=true) + + その後Applyをクリックすると、IDEが再起動を要求します。 + +4. 再起動が完了し、新規プロジェクトを作成すると、golangプロジェクトが作成可能であることがお分かりいただけるかとおもいます: + + ![](images/1.4.idea5.png?raw=true) + + 次に、go sdkの場所を入力するよう促されるかもしれません。普段はいつもC:\Goにインストールされています。Linuxとmacは自分のインストールディレクトリの設定にしたがって、ディレクトリを選択すれば大丈夫です。 + +## links + * [目次]() + * 前へ: [Goのコマンド](<01.3.md>) + * 次へ: [まとめ](<01.5.md>) diff --git a/ja/05.4.md b/ja/05.4.md index a281641a..a9518802 100644 --- a/ja/05.4.md +++ b/ja/05.4.md @@ -1,124 +1,124 @@ -# 5.4 PostgreSQLデータベースの使用 - -PostgreSQLはフリーなオブジェクト-リレーショナルデータベースサーバ(データベース管理システム)です。これは活発なBSDライクなライセンスで公開されています。他のオープンソースなデータベースシステム(MySQLやFirebird)やOracle、Sybase、IBMのDB2やMicrosoft SQL Serverといったプロプライエタリなシステムに対する選択肢の一つです。 - -PostgreSQLとMySQLを比較すると、これは少々巨大です。これはOracleの代替として設計されているためです。そのため、企業のアプリケーションではPostgreSQLを選択することが賢い選択の一つとなっています。 - -MySQLはOracleに買収され、現在徐々にクローズされつつあります。(MySQL 5.5.31以降のすべてのバージョンがGPLライセンスを順守していません)。これに鑑み、将来我々もプロジェクトのバックエンドのデータベースとしてMySQLではなくPostgreSQLを選択することになるかもしれません。 - -## ドライバ -GoはPostgreSQLをサポートしたドライバも非常に多く実装されています。国外では多くの人が開発でこのデータベースを使用しているためです。 - -- https://github.com/lib/pq database/sqlドライバをサポートしています。純粋にGoで書かれています。 -- https://github.com/jbarham/gopgsqldriver database/sqlドライバをサポートしています。純粋にGoで書かれています。 -- https://github.com/lxn/go-pgsql database/sqlドライバをサポートしています。純粋にGoで書かれています。 - -下の例では一つ目のドライバを採用してご説明します。これは使用している人が最も多く、githubでも比較的活発であるからです。 - -## 実例コード -データベースのテーブル作成文: - - CREATE TABLE userinfo - ( - uid serial NOT NULL, - username character varying(100) NOT NULL, - department character varying(500) NOT NULL, - Created date, - CONSTRAINT userinfo_pkey PRIMARY KEY (uid) - ) - WITH (OIDS=FALSE); - - CREATE TABLE userdeatail - ( - uid integer, - intro character varying(100), - profile character varying(100) - ) - WITH(OIDS=FALSE); - -下ではGoがどのようにデータベースのテーブルのデータを操作するか見て行きましょう:追加・削除・修正・検索 - -package main - - import ( - "database/sql" - "fmt" - _ "https://github.com/lib/pq" - ) - - func main() { - db, err := sql.Open("postgres", "user=astaxie password=astaxie dbname=test sslmode=disable") - checkErr(err) - - //データの挿入 - stmt, err := db.Prepare("INSERT INTO userinfo(username,department,created) VALUES($1,$2,$3) RETURNING uid") - checkErr(err) - - res, err := stmt.Exec("astaxie", "研究開発部門", "2012-12-09") - checkErr(err) - - //pgはこの関数をサポートしていません。MySQLのインクリメンタルなIDのようなものが無いためです。 - id, err := res.LastInsertId() - checkErr(err) - - fmt.Println(id) - - //データの更新 - stmt, err = db.Prepare("update userinfo set username=$1 where uid=$2") - checkErr(err) - - res, err = stmt.Exec("astaxieupdate", 1) - checkErr(err) - - affect, err := res.RowsAffected() - checkErr(err) - - fmt.Println(affect) - - //データの検索 - rows, err := db.Query("SELECT * FROM userinfo") - checkErr(err) - - for rows.Next() { - var uid int - var username string - var department string - var created string - err = rows.Scan(&uid, &username, &department, &created) - checkErr(err) - fmt.Println(uid) - fmt.Println(username) - fmt.Println(department) - fmt.Println(created) - } - - //データの削除 - stmt, err = db.Prepare("delete from userinfo where uid=$1") - checkErr(err) - - res, err = stmt.Exec(1) - checkErr(err) - - affect, err = res.RowsAffected() - checkErr(err) - - fmt.Println(affect) - - db.Close() - - } - - func checkErr(err error) { - if err != nil { - panic(err) - } - } - -上のコードによって、PostgreSQLが`$1`や`$2`といった方法によって引数を渡している様子がお分かりいただけるかとおもいます。MySQLの中の`?`ではありません。また、sql.Openではdsn情報のシンタックスがMySQLのドライバでのdsnシンタックスと異なります。そのため、使用される際はこの違いにご注意ください。 - -また、pgはLastInsertId関数をサポートしていません。PostgreSQLの内部ではMySQLのインクリメンタルなIDを返すといった実装がないためです。その他のコードはほとんど同じです。 - -## links - * [目次]() - * 前へ: [SQLiteデータベースの使用](<05.3.md>) - * 次へ: [beedbライブラリを使ってORM開発を行う](<05.5.md>) +# 5.4 PostgreSQLデータベースの使用 + +PostgreSQLはフリーなオブジェクト-リレーショナルデータベースサーバ(データベース管理システム)です。これは活発なBSDライクなライセンスで公開されています。他のオープンソースなデータベースシステム(MySQLやFirebird)やOracle、Sybase、IBMのDB2やMicrosoft SQL Serverといったプロプライエタリなシステムに対する選択肢の一つです。 + +PostgreSQLとMySQLを比較すると、これは少々巨大です。これはOracleの代替として設計されているためです。そのため、企業のアプリケーションではPostgreSQLを選択することが賢い選択の一つとなっています。 + +MySQLはOracleに買収され、現在徐々にクローズされつつあります。(MySQL 5.5.31以降のすべてのバージョンがGPLライセンスを順守していません)。これに鑑み、将来我々もプロジェクトのバックエンドのデータベースとしてMySQLではなくPostgreSQLを選択することになるかもしれません。 + +## ドライバ +GoはPostgreSQLをサポートしたドライバも非常に多く実装されています。国外では多くの人が開発でこのデータベースを使用しているためです。 + +- https://github.com/lib/pq database/sqlドライバをサポートしています。純粋にGoで書かれています。 +- https://github.com/jbarham/gopgsqldriver database/sqlドライバをサポートしています。純粋にGoで書かれています。 +- https://github.com/lxn/go-pgsql database/sqlドライバをサポートしています。純粋にGoで書かれています。 + +下の例では一つ目のドライバを採用してご説明します。これは使用している人が最も多く、GitHubでも比較的活発であるからです。 + +## 実例コード +データベースのテーブル作成文: + + CREATE TABLE userinfo + ( + uid serial NOT NULL, + username character varying(100) NOT NULL, + department character varying(500) NOT NULL, + Created date, + CONSTRAINT userinfo_pkey PRIMARY KEY (uid) + ) + WITH (OIDS=FALSE); + + CREATE TABLE userdeatail + ( + uid integer, + intro character varying(100), + profile character varying(100) + ) + WITH(OIDS=FALSE); + +下ではGoがどのようにデータベースのテーブルのデータを操作するか見て行きましょう:追加・削除・修正・検索 + +package main + + import ( + "database/sql" + "fmt" + _ "https://github.com/lib/pq" + ) + + func main() { + db, err := sql.Open("postgres", "user=astaxie password=astaxie dbname=test sslmode=disable") + checkErr(err) + + //データの挿入 + stmt, err := db.Prepare("INSERT INTO userinfo(username,department,created) VALUES($1,$2,$3) RETURNING uid") + checkErr(err) + + res, err := stmt.Exec("astaxie", "研究開発部門", "2012-12-09") + checkErr(err) + + //pgはこの関数をサポートしていません。MySQLのインクリメンタルなIDのようなものが無いためです。 + id, err := res.LastInsertId() + checkErr(err) + + fmt.Println(id) + + //データの更新 + stmt, err = db.Prepare("update userinfo set username=$1 where uid=$2") + checkErr(err) + + res, err = stmt.Exec("astaxieupdate", 1) + checkErr(err) + + affect, err := res.RowsAffected() + checkErr(err) + + fmt.Println(affect) + + //データの検索 + rows, err := db.Query("SELECT * FROM userinfo") + checkErr(err) + + for rows.Next() { + var uid int + var username string + var department string + var created string + err = rows.Scan(&uid, &username, &department, &created) + checkErr(err) + fmt.Println(uid) + fmt.Println(username) + fmt.Println(department) + fmt.Println(created) + } + + //データの削除 + stmt, err = db.Prepare("delete from userinfo where uid=$1") + checkErr(err) + + res, err = stmt.Exec(1) + checkErr(err) + + affect, err = res.RowsAffected() + checkErr(err) + + fmt.Println(affect) + + db.Close() + + } + + func checkErr(err error) { + if err != nil { + panic(err) + } + } + +上のコードによって、PostgreSQLが`$1`や`$2`といった方法によって引数を渡している様子がお分かりいただけるかとおもいます。MySQLの中の`?`ではありません。また、sql.Openではdsn情報のシンタックスがMySQLのドライバでのdsnシンタックスと異なります。そのため、使用される際はこの違いにご注意ください。 + +また、pgはLastInsertId関数をサポートしていません。PostgreSQLの内部ではMySQLのインクリメンタルなIDを返すといった実装がないためです。その他のコードはほとんど同じです。 + +## links + * [目次]() + * 前へ: [SQLiteデータベースの使用](<05.3.md>) + * 次へ: [beedbライブラリを使ってORM開発を行う](<05.5.md>) diff --git a/ja/13.6.md b/ja/13.6.md index cf4638f7..8face232 100644 --- a/ja/13.6.md +++ b/ja/13.6.md @@ -1,7 +1,7 @@ -# 13.6 まとめ -この章ではどのように基礎的なGo言語のフレームワークを実装するかについてご紹介しました。フレームワークにはルーティング設計が含まれます。Goのビルトインのhttpパッケージにあるルーティングにはいくつか足りない部分があるため、我々は動的なルーティング規則を設計し、その後MVCモデルにおけるController設計をご紹介しました。controllerはRESTを実装しており、主な考え方はtornadeフレームワークからきています。次にも出るのlayoutおよびテンプレートの自動化技術を実装しました。主に採用したのはGoのビルトインのモデルエンジンです。最後に補足的なログ、設定といった情報の設計をご紹介しました。これらの設計を通して基礎的なフレームワークbeegoを実装しました。現在このフレームワークはすでにgithub上でオープンソースになっています。最後に我々はbeegoを通じてブログシステムの実装を行いました。この実例コードを通してどのように快速にホームページを開発するのかが見渡せたのではないかと思います。 - -## links - * [目次]() - * 前へ: [ブログの追加/削除/修正の実装](<13.5.md>) - * 次へ: [Webフレームワークの拡張](<14.0.md>) +# 13.6 まとめ +この章ではどのように基礎的なGo言語のフレームワークを実装するかについてご紹介しました。フレームワークにはルーティング設計が含まれます。Goのビルトインのhttpパッケージにあるルーティングにはいくつか足りない部分があるため、我々は動的なルーティング規則を設計し、その後MVCモデルにおけるController設計をご紹介しました。controllerはRESTを実装しており、主な考え方はtornadeフレームワークからきています。次にも出るのlayoutおよびテンプレートの自動化技術を実装しました。主に採用したのはGoのビルトインのモデルエンジンです。最後に補足的なログ、設定といった情報の設計をご紹介しました。これらの設計を通して基礎的なフレームワークbeegoを実装しました。現在このフレームワークはすでにGitHub上でオープンソースになっています。最後に我々はbeegoを通じてブログシステムの実装を行いました。この実例コードを通してどのように快速にホームページを開発するのかが見渡せたのではないかと思います。 + +## links + * [目次]() + * 前へ: [ブログの追加/削除/修正の実装](<13.5.md>) + * 次へ: [Webフレームワークの拡張](<14.0.md>) diff --git a/ja/14.4.md b/ja/14.4.md index 74a69b00..0219eebd 100644 --- a/ja/14.4.md +++ b/ja/14.4.md @@ -1,259 +1,259 @@ -# 14.4 ユーザの認証 -Webアプリケーションを開発する過程で、ユーザ認証は開発者がよくぶつかる問題です。ユーザのログイン、サインアップ、ログアウト等といった操作で、一般的な認証は3つの方面の認証に分けることができます - -- HTTP BasicとHTTP Digest認証 -- サードパーティ認証:QQ、weibo、doubian、OPENID、google、github、facebookおよびtwitterなどです -- カスタム定義のユーザログイン、サインアップ、ログアウトは一般的にsession、cookie認証にもとづいています。 - -beegoは現在この3つの方式のどの形式にも対応していません。しかしサードパーティのオープンソースライブラリによって上の3つの方法のユーザ認証を実装することができます。しかし後々beegoは前者2つの認証を一つ一つ実装するかもしれません。 - -## HTTP BasicとHTTP Digest認証 -この2つの認証はいくつかのアプリケーションが採用している比較的簡単な認証です。現在すでにオープンソースのサードパーティライブラリでこの2つの認証をサポートしています; - - github.com/abbot/go-http-auth - -下のコードはこれらのライブラリをどのようにbeegoに導入するかを示しています: - - package controllers - - import ( - "github.com/abbot/go-http-auth" - "github.com/astaxie/beego" - ) - - func Secret(user, realm string) string { - if user == "john" { - // password is "hello" - return "$1$dlPL2MqE$oQmn16q49SqdmhenQuNgs1" - } - return "" - } - - type MainController struct { - beego.Controller - } - - func (this *MainController) Prepare() { - a := auth.NewBasicAuthenticator("example.com", Secret) - if username := a.CheckAuth(this.Ctx.Request); username == "" { - a.RequireAuth(this.Ctx.ResponseWriter, this.Ctx.Request) - } - } - - func (this *MainController) Get() { - this.Data["Username"] = "astaxie" - this.Data["Email"] = "astaxie@gmail.com" - this.TplNames = "index.tpl" - } - -上のコードはbeegoのprepare関数を利用しています。正常なロジックを実行する前に認証関数をコールすることで、非常に簡単にhttp authを実装しています。digest認証も同様の原理です。 - -## oauthとoauth2の認証 -oauthとoauth2は現在比較的流行している二種類の認証方式です。サードパーティでちょうどこの認証を実装しているライブラリがあるのですが、国外で実装されたもので、QQ、weiboといった中国国内のアプリケーション認証はありません。 - - github.com/bradrydzewski/go.auth - -下のコードはどのようにしてこのライブラリをbeegoの中に導入しoauth認証を実装するか示しています。ここではgithubを例にしています: - -1. ルーティングを2本追加 - - beego.RegisterController("/auth/login", &controllers.GithubController{}) - beego.RegisterController("/mainpage", &controllers.PageController{}) - -2. 次にGithubControllerログインの画面を処理: - - package controllers - - import ( - "github.com/astaxie/beego" - "github.com/bradrydzewski/go.auth" - ) - - const ( - githubClientKey = "a0864ea791ce7e7bd0df" - githubSecretKey = "a0ec09a647a688a64a28f6190b5a0d2705df56ca" - ) - - type GithubController struct { - beego.Controller - } - - func (this *GithubController) Get() { - // set the auth parameters - auth.Config.CookieSecret = []byte("7H9xiimk2QdTdYI7rDddfJeV") - auth.Config.LoginSuccessRedirect = "/mainpage" - auth.Config.CookieSecure = false - - githubHandler := auth.Github(githubClientKey, githubSecretKey) - - githubHandler.ServeHTTP(this.Ctx.ResponseWriter, this.Ctx.Request) - } - - -3. ログインに成功した後のページ画面を処理 - - package controllers - - import ( - "github.com/astaxie/beego" - "github.com/bradrydzewski/go.auth" - "net/http" - "net/url" - ) - - type PageController struct { - beego.Controller - } - - func (this *PageController) Get() { - // set the auth parameters - auth.Config.CookieSecret = []byte("7H9xiimk2QdTdYI7rDddfJeV") - auth.Config.LoginSuccessRedirect = "/mainpage" - auth.Config.CookieSecure = false - - user, err := auth.GetUserCookie(this.Ctx.Request) - - //if no active user session then authorize user - if err != nil || user.Id() == "" { - http.Redirect(this.Ctx.ResponseWriter, this.Ctx.Request, auth.Config.LoginRedirect, http.StatusSeeOther) - return - } - - //else, add the user to the URL and continue - this.Ctx.Request.URL.User = url.User(user.Id()) - this.Data["pic"] = user.Picture() - this.Data["id"] = user.Id() - this.Data["name"] = user.Name() - this.TplNames = "home.tpl" - } - -全体の流れは以下のようになります。まずブラウザを開いてアドレスを入力します: - -![](images/14.4.github.png?raw=true) - -図14.4 ログインボタンを持つトップページの表示 - -次にリンクをクリックすると以下のようなインターフェースが現れます: - -![](images/14.4.github2.png?raw=true) - -図14.5 ログインボタンをクリックしてgithubの権限取得ページを表示 - -Authorize appをクリックすると以下のようなインターフェースが現れます: - -![](images/14.4.github3.png?raw=true) - -図14.6 権限取得にログインした後表示される取得済みのgithub情報のページ - -## カスタム定義認証 -カスタム定義の認証は一般的にはsessionと組み合わせて検証されます。以下のコードはあるbeegoのオープンソースブログに基づいています: - - - //ログイン処理 - func (this *LoginController) Post() { - this.TplNames = "login.tpl" - this.Ctx.Request.ParseForm() - username := this.Ctx.Request.Form.Get("username") - password := this.Ctx.Request.Form.Get("password") - md5Password := md5.New() - io.WriteString(md5Password, password) - buffer := bytes.NewBuffer(nil) - fmt.Fprintf(buffer, "%x", md5Password.Sum(nil)) - newPass := buffer.String() - - now := time.Now().Format("2006-01-02 15:04:05") - - userInfo := models.GetUserInfo(username) - if userInfo.Password == newPass { - var users models.User - users.Last_logintime = now - models.UpdateUserInfo(users) - - //ログイン成功でsessionを設定 - sess := globalSessions.SessionStart(this.Ctx.ResponseWriter, this.Ctx.Request) - sess.Set("uid", userInfo.Id) - sess.Set("uname", userInfo.Username) - - this.Ctx.Redirect(302, "/") - } - } - - //サインアップ処理 - func (this *RegController) Post() { - this.TplNames = "reg.tpl" - this.Ctx.Request.ParseForm() - username := this.Ctx.Request.Form.Get("username") - password := this.Ctx.Request.Form.Get("password") - usererr := checkUsername(username) - fmt.Println(usererr) - if usererr == false { - this.Data["UsernameErr"] = "Username error, Please to again" - return - } - - passerr := checkPassword(password) - if passerr == false { - this.Data["PasswordErr"] = "Password error, Please to again" - return - } - - md5Password := md5.New() - io.WriteString(md5Password, password) - buffer := bytes.NewBuffer(nil) - fmt.Fprintf(buffer, "%x", md5Password.Sum(nil)) - newPass := buffer.String() - - now := time.Now().Format("2006-01-02 15:04:05") - - userInfo := models.GetUserInfo(username) - - if userInfo.Username == "" { - var users models.User - users.Username = username - users.Password = newPass - users.Created = now - users.Last_logintime = now - models.AddUser(users) - - //ログイン成功でsessionを設定 - sess := globalSessions.SessionStart(this.Ctx.ResponseWriter, this.Ctx.Request) - sess.Set("uid", userInfo.Id) - sess.Set("uname", userInfo.Username) - this.Ctx.Redirect(302, "/") - } else { - this.Data["UsernameErr"] = "User already exists" - } - - } - - func checkPassword(password string) (b bool) { - if ok, _ := regexp.MatchString("^[a-zA-Z0-9]{4,16}$", password); !ok { - return false - } - return true - } - - func checkUsername(username string) (b bool) { - if ok, _ := regexp.MatchString("^[a-zA-Z0-9]{4,16}$", username); !ok { - return false - } - return true - } - -ユーザのログインとサインアップがあって、その他のモジュールでも以下のようにユーザがログインしているかどうかの判断を追加することができます: - - func (this *AddBlogController) Prepare() { - sess := globalSessions.SessionStart(this.Ctx.ResponseWriter, this.Ctx.Request) - sess_uid := sess.Get("userid") - sess_username := sess.Get("username") - if sess_uid == nil { - this.Ctx.Redirect(302, "/admin/login") - return - } - this.Data["Username"] = sess_username - } - -## links - * [目次]() - * 前へ: [フォームおよび検証のサポート](<14.3.md>) - * 次へ: [多言語サポート](<14.5.md>) +# 14.4 ユーザの認証 +Webアプリケーションを開発する過程で、ユーザ認証は開発者がよくぶつかる問題です。ユーザのログイン、サインアップ、ログアウト等といった操作で、一般的な認証は3つの方面の認証に分けることができます + +- HTTP BasicとHTTP Digest認証 +- サードパーティ認証:QQ、weibo、doubian、OPENID、google、GitHub、facebookおよびtwitterなどです +- カスタム定義のユーザログイン、サインアップ、ログアウトは一般的にsession、cookie認証にもとづいています。 + +beegoは現在この3つの方式のどの形式にも対応していません。しかしサードパーティのオープンソースライブラリによって上の3つの方法のユーザ認証を実装することができます。しかし後々beegoは前者2つの認証を一つ一つ実装するかもしれません。 + +## HTTP BasicとHTTP Digest認証 +この2つの認証はいくつかのアプリケーションが採用している比較的簡単な認証です。現在すでにオープンソースのサードパーティライブラリでこの2つの認証をサポートしています; + + github.com/abbot/go-http-auth + +下のコードはこれらのライブラリをどのようにbeegoに導入するかを示しています: + + package controllers + + import ( + "github.com/abbot/go-http-auth" + "github.com/astaxie/beego" + ) + + func Secret(user, realm string) string { + if user == "john" { + // password is "hello" + return "$1$dlPL2MqE$oQmn16q49SqdmhenQuNgs1" + } + return "" + } + + type MainController struct { + beego.Controller + } + + func (this *MainController) Prepare() { + a := auth.NewBasicAuthenticator("example.com", Secret) + if username := a.CheckAuth(this.Ctx.Request); username == "" { + a.RequireAuth(this.Ctx.ResponseWriter, this.Ctx.Request) + } + } + + func (this *MainController) Get() { + this.Data["Username"] = "astaxie" + this.Data["Email"] = "astaxie@gmail.com" + this.TplNames = "index.tpl" + } + +上のコードはbeegoのprepare関数を利用しています。正常なロジックを実行する前に認証関数をコールすることで、非常に簡単にhttp authを実装しています。digest認証も同様の原理です。 + +## oauthとoauth2の認証 +oauthとoauth2は現在比較的流行している二種類の認証方式です。サードパーティでちょうどこの認証を実装しているライブラリがあるのですが、国外で実装されたもので、QQ、weiboといった中国国内のアプリケーション認証はありません。 + + github.com/bradrydzewski/go.auth + +下のコードはどのようにしてこのライブラリをbeegoの中に導入しoauth認証を実装するか示しています。ここではGitHubを例にしています: + +1. ルーティングを2本追加 + + beego.RegisterController("/auth/login", &controllers.GithubController{}) + beego.RegisterController("/mainpage", &controllers.PageController{}) + +2. 次にGithubControllerログインの画面を処理: + + package controllers + + import ( + "github.com/astaxie/beego" + "github.com/bradrydzewski/go.auth" + ) + + const ( + githubClientKey = "a0864ea791ce7e7bd0df" + githubSecretKey = "a0ec09a647a688a64a28f6190b5a0d2705df56ca" + ) + + type GithubController struct { + beego.Controller + } + + func (this *GithubController) Get() { + // set the auth parameters + auth.Config.CookieSecret = []byte("7H9xiimk2QdTdYI7rDddfJeV") + auth.Config.LoginSuccessRedirect = "/mainpage" + auth.Config.CookieSecure = false + + githubHandler := auth.Github(githubClientKey, githubSecretKey) + + githubHandler.ServeHTTP(this.Ctx.ResponseWriter, this.Ctx.Request) + } + + +3. ログインに成功した後のページ画面を処理 + + package controllers + + import ( + "github.com/astaxie/beego" + "github.com/bradrydzewski/go.auth" + "net/http" + "net/url" + ) + + type PageController struct { + beego.Controller + } + + func (this *PageController) Get() { + // set the auth parameters + auth.Config.CookieSecret = []byte("7H9xiimk2QdTdYI7rDddfJeV") + auth.Config.LoginSuccessRedirect = "/mainpage" + auth.Config.CookieSecure = false + + user, err := auth.GetUserCookie(this.Ctx.Request) + + //if no active user session then authorize user + if err != nil || user.Id() == "" { + http.Redirect(this.Ctx.ResponseWriter, this.Ctx.Request, auth.Config.LoginRedirect, http.StatusSeeOther) + return + } + + //else, add the user to the URL and continue + this.Ctx.Request.URL.User = url.User(user.Id()) + this.Data["pic"] = user.Picture() + this.Data["id"] = user.Id() + this.Data["name"] = user.Name() + this.TplNames = "home.tpl" + } + +全体の流れは以下のようになります。まずブラウザを開いてアドレスを入力します: + +![](images/14.4.github.png?raw=true) + +図14.4 ログインボタンを持つトップページの表示 + +次にリンクをクリックすると以下のようなインターフェースが現れます: + +![](images/14.4.github2.png?raw=true) + +図14.5 ログインボタンをクリックしてGitHubの権限取得ページを表示 + +Authorize appをクリックすると以下のようなインターフェースが現れます: + +![](images/14.4.github3.png?raw=true) + +図14.6 権限取得にログインした後表示される取得済みのGitHub情報のページ + +## カスタム定義認証 +カスタム定義の認証は一般的にはsessionと組み合わせて検証されます。以下のコードはあるbeegoのオープンソースブログに基づいています: + + + //ログイン処理 + func (this *LoginController) Post() { + this.TplNames = "login.tpl" + this.Ctx.Request.ParseForm() + username := this.Ctx.Request.Form.Get("username") + password := this.Ctx.Request.Form.Get("password") + md5Password := md5.New() + io.WriteString(md5Password, password) + buffer := bytes.NewBuffer(nil) + fmt.Fprintf(buffer, "%x", md5Password.Sum(nil)) + newPass := buffer.String() + + now := time.Now().Format("2006-01-02 15:04:05") + + userInfo := models.GetUserInfo(username) + if userInfo.Password == newPass { + var users models.User + users.Last_logintime = now + models.UpdateUserInfo(users) + + //ログイン成功でsessionを設定 + sess := globalSessions.SessionStart(this.Ctx.ResponseWriter, this.Ctx.Request) + sess.Set("uid", userInfo.Id) + sess.Set("uname", userInfo.Username) + + this.Ctx.Redirect(302, "/") + } + } + + //サインアップ処理 + func (this *RegController) Post() { + this.TplNames = "reg.tpl" + this.Ctx.Request.ParseForm() + username := this.Ctx.Request.Form.Get("username") + password := this.Ctx.Request.Form.Get("password") + usererr := checkUsername(username) + fmt.Println(usererr) + if usererr == false { + this.Data["UsernameErr"] = "Username error, Please to again" + return + } + + passerr := checkPassword(password) + if passerr == false { + this.Data["PasswordErr"] = "Password error, Please to again" + return + } + + md5Password := md5.New() + io.WriteString(md5Password, password) + buffer := bytes.NewBuffer(nil) + fmt.Fprintf(buffer, "%x", md5Password.Sum(nil)) + newPass := buffer.String() + + now := time.Now().Format("2006-01-02 15:04:05") + + userInfo := models.GetUserInfo(username) + + if userInfo.Username == "" { + var users models.User + users.Username = username + users.Password = newPass + users.Created = now + users.Last_logintime = now + models.AddUser(users) + + //ログイン成功でsessionを設定 + sess := globalSessions.SessionStart(this.Ctx.ResponseWriter, this.Ctx.Request) + sess.Set("uid", userInfo.Id) + sess.Set("uname", userInfo.Username) + this.Ctx.Redirect(302, "/") + } else { + this.Data["UsernameErr"] = "User already exists" + } + + } + + func checkPassword(password string) (b bool) { + if ok, _ := regexp.MatchString("^[a-zA-Z0-9]{4,16}$", password); !ok { + return false + } + return true + } + + func checkUsername(username string) (b bool) { + if ok, _ := regexp.MatchString("^[a-zA-Z0-9]{4,16}$", username); !ok { + return false + } + return true + } + +ユーザのログインとサインアップがあって、その他のモジュールでも以下のようにユーザがログインしているかどうかの判断を追加することができます: + + func (this *AddBlogController) Prepare() { + sess := globalSessions.SessionStart(this.Ctx.ResponseWriter, this.Ctx.Request) + sess_uid := sess.Get("userid") + sess_username := sess.Get("username") + if sess_uid == nil { + this.Ctx.Redirect(302, "/admin/login") + return + } + this.Data["Username"] = sess_username + } + +## links + * [目次]() + * 前へ: [フォームおよび検証のサポート](<14.3.md>) + * 次へ: [多言語サポート](<14.5.md>) diff --git a/pt-br/01.2.md b/pt-br/01.2.md index 3f0c8f5a..3cc1d96c 100644 --- a/pt-br/01.2.md +++ b/pt-br/01.2.md @@ -91,7 +91,7 @@ Para compilar nossa aplicação, deveremos alterar o código fonte de diretório ## Instalando pacotes remotamente -Go possui uma ferramenta para utilizar pacotes remotos, chamada `go get`. Ela é suportada por grandes comunidades de código aberto, incluindo: Github, Google Code, Bitbucket e Launchpad. +Go possui uma ferramenta para utilizar pacotes remotos, chamada `go get`. Ela é suportada por grandes comunidades de código aberto, incluindo: GitHub, Google Code, Bitbucket e Launchpad. go get github.com/astaxie/beedb diff --git a/pt-br/01.3.md b/pt-br/01.3.md index 6a933d98..5e163628 100644 --- a/pt-br/01.3.md +++ b/pt-br/01.3.md @@ -56,10 +56,10 @@ Normalmente, usamos o comando `gofmt -w` ao invés de simplesmente `go fmt`. A d ## go get -Esse comando serve para obtenção de pacotes remotamente. Até o momento, o comando suporta BitBucket, Github, Google Code e Launchpad. De fato, duas coisas ocorrem quando esse comando é executado. Primeiramente é feito o download do código fonte e então é executado o comando `go install`. Antes de utilizar esse comando, tenha certeza de possuir instalados as seguintes ferramentas. +Esse comando serve para obtenção de pacotes remotamente. Até o momento, o comando suporta BitBucket, GitHub, Google Code e Launchpad. De fato, duas coisas ocorrem quando esse comando é executado. Primeiramente é feito o download do código fonte e então é executado o comando `go install`. Antes de utilizar esse comando, tenha certeza de possuir instalados as seguintes ferramentas. BitBucket (Mercurial Git) - Github (git) + GitHub (git) Google Code (Git, Mercurial, Subversion) Launchpad (Bazaar) diff --git a/pt-br/12.3.md b/pt-br/12.3.md index 8f46bd75..5b1108aa 100644 --- a/pt-br/12.3.md +++ b/pt-br/12.3.md @@ -4,7 +4,7 @@ When our web application is finally production ready, what are the steps necessa ## Daemons -Currently, Go programs cannot cannot be run as daemon processes (for additional information, see the open issue on github [here](https://github.com/golang/go/issues/227)). It's difficult to fork existing threads in Go because there is no way of ensuring a consistent state in all threads that have been used. +Currently, Go programs cannot cannot be run as daemon processes (for additional information, see the open issue on GitHub [here](https://github.com/golang/go/issues/227)). It's difficult to fork existing threads in Go because there is no way of ensuring a consistent state in all threads that have been used. We can, however, see many attempts at implementing daemons online, such as in the two following ways; diff --git a/pt-br/14.4.md b/pt-br/14.4.md index 2bc3cf84..15f20a88 100644 --- a/pt-br/14.4.md +++ b/pt-br/14.4.md @@ -56,7 +56,7 @@ OAuth and OAuth 2 are currently two of the most popular authentication methods. github.com/bradrydzewski/go.auth -The code below demonstrates how to use this library to implement OAuth authentication in Beego using our Github credentials: +The code below demonstrates how to use this library to implement OAuth authentication in Beego using our GitHub credentials: 1. Let's add some routes @@ -147,7 +147,7 @@ After clicking "Authorize app", the following screen appears: ![](images/14.4.github3.png?raw=true) -Figure 14.6 authorized Github information gets displayed after the login page +Figure 14.6 authorized GitHub information gets displayed after the login page ## Custom authentication diff --git a/ru/01.2.md b/ru/01.2.md index 92aa57a9..e8def99d 100644 --- a/ru/01.2.md +++ b/ru/01.2.md @@ -90,13 +90,13 @@ func main() { ## Установка удаленных пакетов -В Go есть инструмент для установки удаленных пакетов - команда `go get`. Он поддерживает работу с большинством сообществ Open Source, включая Github, Google Code, BitBucket и Launchpad. +В Go есть инструмент для установки удаленных пакетов - команда `go get`. Он поддерживает работу с большинством сообществ Open Source, включая GitHub, Google Code, BitBucket и Launchpad. go get github.com/astaxie/beedb Чтобы обновить Ваши удаленные пакеты, выполните `go get -u …`, при этом установятся все дополнительные зависимости . -Для разных Open Source платформ потребуются различные системы контроля версий, например `git` для Github и `hg` для Google Code. Поэтому Вам нужно установить соответствующие системы контроля версий перед использованием `go get`. +Для разных Open Source платформ потребуются различные системы контроля версий, например `git` для GitHub и `hg` для Google Code. Поэтому Вам нужно установить соответствующие системы контроля версий перед использованием `go get`. После выполнения команд выше структура каталогов будет выглядеть следующим образом: diff --git a/ru/01.3.md b/ru/01.3.md index abe6be13..3e10e18c 100644 --- a/ru/01.3.md +++ b/ru/01.3.md @@ -55,10 +55,10 @@ ## go get -Эта команда служит для установки удаленных пакетов. На данный момент она поддерживает BitBucket, Github, Google Code и Launchpad. При запуске этой команды происходят вещи: первая - Go скачивает исходники пакетов, вторая - исполняется `go install`. Перед использованием этой команды убедитесь, что у Вас установлены соответствующие инструменты: +Эта команда служит для установки удаленных пакетов. На данный момент она поддерживает BitBucket, GitHub, Google Code и Launchpad. При запуске этой команды происходят вещи: первая - Go скачивает исходники пакетов, вторая - исполняется `go install`. Перед использованием этой команды убедитесь, что у Вас установлены соответствующие инструменты: BitBucket (Mercurial Git) - Github (git) + GitHub (git) Google Code (Git, Mercurial, Subversion) Launchpad (Bazaar) diff --git a/ru/01.4.md b/ru/01.4.md index 168684da..ce08f584 100644 --- a/ru/01.4.md +++ b/ru/01.4.md @@ -327,7 +327,7 @@ Eclipse также является отличным инструментом р 2. Скачайте [goclipse](https://code.google.com/p/goclipse/) [http://code.google.com/p/goclipse/wiki/InstallationInstructions](http://code.google.com/p/goclipse/wiki/InstallationInstructions). 3. Скачайте gocode: - gocode на Github: + gocode на GitHub: https://github.com/nsf/gocode diff --git a/th/01.2.md b/th/01.2.md index 5fae9602..cd8c9ffb 100644 --- a/th/01.2.md +++ b/th/01.2.md @@ -96,13 +96,13 @@ func main() { ## การติดตั้ง package เพิ่มเติม -Go มาพร้อมกับเครื่องมือที่ใช้ในการติดตั้ง package เสริม ซึ่งได้แก่คำสั่งที่เรียกว่า `go get` โดยรองรับ opensource comunity เกือบทุกที่ รวมถึง Github, Google Code, BitBucket และ Launchpad +Go มาพร้อมกับเครื่องมือที่ใช้ในการติดตั้ง package เสริม ซึ่งได้แก่คำสั่งที่เรียกว่า `go get` โดยรองรับ opensource comunity เกือบทุกที่ รวมถึง GitHub, Google Code, BitBucket และ Launchpad go get github.com/astaxie/beedb โดยสามารถใช้ `go get -u …` ในการอัพเดท package และยังสามารถติดตั้ง package ที่เป็น dependency ให้โดยอัตโนมัติด้วย -ซึ่งเครื่องมือนี้จะใช้ version control ที่แตกต่างกันสำหรับแต่ละ opensource platform ยกตัวอย่างเช่น จะใช้่่ `git` สำหรับ Github และใช้ `hg` สำหรับ Google Code ดังนั้นเราจำเป็นที่จะต้องติดตั้งเครื่องมือ version control เหล่านี้ก่อนที่เราจะใช้ `go get` ได้ +ซึ่งเครื่องมือนี้จะใช้ version control ที่แตกต่างกันสำหรับแต่ละ opensource platform ยกตัวอย่างเช่น จะใช้่่ `git` สำหรับ GitHub และใช้ `hg` สำหรับ Google Code ดังนั้นเราจำเป็นที่จะต้องติดตั้งเครื่องมือ version control เหล่านี้ก่อนที่เราจะใช้ `go get` ได้ หลังจากที่รันคำสั่งที่กล่าวมาแล้ว โครงสร้างไดเร็คทอรีควรมีหน้าตาดังนี้ diff --git a/th/01.3.md b/th/01.3.md index 02a2b4a7..efb894ba 100644 --- a/th/01.3.md +++ b/th/01.3.md @@ -43,7 +43,7 @@ DIR.test(.exe) // สร้างจากคำสั่ง go test -c MAINFILE(.exe) // สร้างจากคำสั่ง go build MAINFILE.go -โดยปรกติผมจะใช้คำสั่งนี้เพื่อลบไฟล์ที่ไม่ต้องการก่อนที่จะอัพโหลดโปรเจ็คไปที่ Github ซึ่งไฟล์เหล่านี้มีประโยชน์ในการทำงานบนเครื่อง แต่ไม่ได้มีประโยชน์กับ version control +โดยปรกติผมจะใช้คำสั่งนี้เพื่อลบไฟล์ที่ไม่ต้องการก่อนที่จะอัพโหลดโปรเจ็คไปที่ GitHub ซึ่งไฟล์เหล่านี้มีประโยชน์ในการทำงานบนเครื่อง แต่ไม่ได้มีประโยชน์กับ version control ## go fmt และ gofmt @@ -56,10 +56,10 @@ ## go get -คำสั่งนี้จะเป็นการดึง package มาใช้งานจากเครื่องอื่น โดยตั้งแต่ต้นนั้นจะ support การดึงมาจาก BitBucket, Github, Google Code และ Launchpad โดยจะเกิดการทำงานสองอย่างขึ้นจากการสั่งคำสั่งนี้ อย่างแรกคือ Go จะดาวน์โหลด source code มา เสร็จแล้วจะสั่ง `go install` ให้เองเลย แต่ก่อนที่เราจะใช้คำสั่งนี้ กรุณาตรวจสอบให้มั่นใจว่ามีการติดตั้งเครื่องมือที่เกี่ยวข้องไว้ก่อนแล้ว ดังนี้ +คำสั่งนี้จะเป็นการดึง package มาใช้งานจากเครื่องอื่น โดยตั้งแต่ต้นนั้นจะ support การดึงมาจาก BitBucket, GitHub, Google Code และ Launchpad โดยจะเกิดการทำงานสองอย่างขึ้นจากการสั่งคำสั่งนี้ อย่างแรกคือ Go จะดาวน์โหลด source code มา เสร็จแล้วจะสั่ง `go install` ให้เองเลย แต่ก่อนที่เราจะใช้คำสั่งนี้ กรุณาตรวจสอบให้มั่นใจว่ามีการติดตั้งเครื่องมือที่เกี่ยวข้องไว้ก่อนแล้ว ดังนี้ BitBucket (Mercurial Git) - Github (git) + GitHub (git) Google Code (Git, Mercurial, Subversion) Launchpad (Bazaar) diff --git a/th/02.1.md b/th/02.1.md index 63e1e881..2aab7016 100644 --- a/th/02.1.md +++ b/th/02.1.md @@ -23,7 +23,7 @@ To mitigate all the problems that Google faced with current tools, they wrote a Go was designed with concurrency in mind, please note that parallelism != concurrency, there is an [amazing post](https://blog.golang.org/concurrency-is-not-parallelism) by Rob Pike on the [golang blog](https://blog.golang.org/), you will find it there, it is worth a read. -Another very important change that is the concept of `GOPATH`. Gone are the days when you had to create a folder called `code` and then create workspaces for eclipse and what not. Now you have to keep one folder tree for go code which will be updated by the package manager automatically. It is also recommended to create folders with either a custom domain or the github domain, for example I created a task manager using golang so I created a set of folders +Another very important change that is the concept of `GOPATH`. Gone are the days when you had to create a folder called `code` and then create workspaces for eclipse and what not. Now you have to keep one folder tree for go code which will be updated by the package manager automatically. It is also recommended to create folders with either a custom domain or the GitHub domain, for example I created a task manager using golang so I created a set of folders `~/go/src/github.com/thewhitetulip/Tasks` **Note:** In *nix systems `~` stands for home directory, which is the windows equivalent of `C:\\Users\\username`. diff --git a/th/12.3.md b/th/12.3.md index d9919a06..77cac455 100644 --- a/th/12.3.md +++ b/th/12.3.md @@ -4,7 +4,7 @@ When our web application is finally production ready, what are the steps necessa ## Daemons -Currently, Go programs cannot be run as daemon processes (for additional information, see the open issue on github [here](https://github.com/golang/go/issues/227)). It's difficult to fork existing threads in Go because there is no way of ensuring a consistent state in all threads that have been used. +Currently, Go programs cannot be run as daemon processes (for additional information, see the open issue on GitHub [here](https://github.com/golang/go/issues/227)). It's difficult to fork existing threads in Go because there is no way of ensuring a consistent state in all threads that have been used. We can, however, see many attempts at implementing daemons online, such as in the two following ways; diff --git a/th/14.4.md b/th/14.4.md index 79b61675..5c7e754d 100644 --- a/th/14.4.md +++ b/th/14.4.md @@ -56,7 +56,7 @@ OAuth and OAuth 2 are currently two of the most popular authentication methods. github.com/bradrydzewski/go.auth -The code below demonstrates how to use this library to implement OAuth authentication in Beego using our Github credentials: +The code below demonstrates how to use this library to implement OAuth authentication in Beego using our GitHub credentials: 1. Let's add some routes @@ -147,7 +147,7 @@ After clicking "Authorize app", the following screen appears: ![](images/14.4.github3.png?raw=true) -Figure 14.6 authorized Github information gets displayed after the login page +Figure 14.6 authorized GitHub information gets displayed after the login page ## Custom authentication diff --git a/tr/01.2.md b/tr/01.2.md index 85fd3b3d..f1330692 100644 --- a/tr/01.2.md +++ b/tr/01.2.md @@ -90,7 +90,7 @@ Uygulamyı derlemek için, `$GOPATH/src/mathapp` dizinine geçip, `go install` k ## Üçüncü-parti paketleri kurmak -Üçüncü-parti paketleri kurmak için `go get` komutunu kullanabilirsiniz. Bir çok açık-kaynak platformu destekliyor; Github, Google Code, BitBucket, ve Launchpad. +Üçüncü-parti paketleri kurmak için `go get` komutunu kullanabilirsiniz. Bir çok açık-kaynak platformu destekliyor; GitHub, Google Code, BitBucket, ve Launchpad. go get github.com/astaxie/beedb diff --git a/tr/01.3.md b/tr/01.3.md index f068a058..774336ee 100644 --- a/tr/01.3.md +++ b/tr/01.3.md @@ -43,7 +43,7 @@ Derleyici tarafından oluşturulmuş aşağıdaki dosyaları temizler: DIR.test(.exe) // go test -c tarafından oluşturulmuş MAINFILE(.exe) // go build MAINFILE.go tarafından oluşturulmuş -Projelerimi Github'a göndermeden önce genellikle bu komutu çalıştırırım. Yereldeki testler için önemli, ama sürüm takip için gereksiz dosyalar. +Projelerimi GitHub'a göndermeden önce genellikle bu komutu çalıştırırım. Yereldeki testler için önemli, ama sürüm takip için gereksiz dosyalar. ## go fmt @@ -56,10 +56,10 @@ Projelerimi Github'a göndermeden önce genellikle bu komutu çalıştırırım. ## go get -Bu komut üçüncü parti paketleri almanızı sağlar. Şuanda; BitBucket, Github, Google Code ve Launchpad desteği sunuyor. Bu komutu çalıştırdığımızda iki şey yapılıyor. Birincisi Go kaynak kodunu indiriyor, ikinci olarakta `go install` komutunu çalıştırıyor. Bu komutu çalıştırmadan önce, gerekli araçları kurduğunuzdan emin olun. +Bu komut üçüncü parti paketleri almanızı sağlar. Şuanda; BitBucket, GitHub, Google Code ve Launchpad desteği sunuyor. Bu komutu çalıştırdığımızda iki şey yapılıyor. Birincisi Go kaynak kodunu indiriyor, ikinci olarakta `go install` komutunu çalıştırıyor. Bu komutu çalıştırmadan önce, gerekli araçları kurduğunuzdan emin olun. BitBucket (Mercurial Git) - Github (git) + GitHub (git) Google Code (Git, Mercurial, Subversion) Launchpad (Bazaar) diff --git a/tr/01.4.md b/tr/01.4.md index eea56ff8..bd57953c 100644 --- a/tr/01.4.md +++ b/tr/01.4.md @@ -315,7 +315,7 @@ Eclipse'de çok tutulan geliştirme araçlarındandır. Size Eclipse ile nasıl [http://code.google.com/p/goclipse/wiki/InstallationInstructions](http://code.google.com/p/goclipse/wiki/InstallationInstructions) 3. gocode indirin - Github'dan gocode. + GitHub'dan gocode. https://github.com/nsf/gocode diff --git a/zh-tw/01.2.md b/zh-tw/01.2.md index dd8d774f..5bbd467b 100644 --- a/zh-tw/01.2.md +++ b/zh-tw/01.2.md @@ -1,191 +1,191 @@ -# 1.2 GOPATH 與工作空間 - -前面我們在安裝 Go 的時候看到需要設定 GOPATH 變數,Go 從 1.1 版本到 1.7 必須設定這個變數,而且不能和 Go 的安裝目錄一樣,這個目錄用來存放 Go 原始碼,Go 的可執行檔案,以及相應的編譯之後的套件檔案。所以這個目錄下面有三個子目錄:src、bin、pkg - -從 go 1.8 開始,GOPATH 環境變數現在有一個預設值,如果它沒有被設定。 它在 Unix 上預設為$HOME/go,在 Windows 上預設為%USERPROFILE%/go。 -## GOPATH 設定 - go 命令依賴一個重要的環境變數:$GOPATH - - Windows 系統中環境變數的形式為`%GOPATH%`,本書主要使用 Unix 形式,Windows 使用者請自行替換。 - - *(注:這個不是 Go 安裝目錄。下面以筆者的工作目錄為範例,如果你想不一樣請把 GOPATH 替換成你的工作目錄。)* - - 在類別 Unix 環境下大概這樣設定: - -```sh -export GOPATH=/home/apple/mygo -``` - 為了方便,應該建立以上資料夾,並且上一行加入到 `.bashrc` 或者 `.zshrc` 或者自己的 `sh` 的配置檔案中。 - - Windows 設定如下,建立一個環境變數名稱叫做 GOPATH: - -```sh -GOPATH=c:\mygo -``` -GOPATH 允許多個目錄,當有多個目錄時,請注意分隔符,多個目錄的時候 Windows 是分號,Linux 系統是冒號,當有多個 GOPATH 時,預設會將 go get 的內容放在第一個目錄下。 - - -以上 $GOPATH 目錄約定有三個子目錄: - -- src 存放原始碼(比如:.go .c .h .s 等) -- pkg 編譯後生成的檔案(比如:.a) -- bin 編譯後生成的可執行檔案(為了方便,可以把此目錄加入到 $PATH 變數中,如果有多個 gopath,那麼使用`${GOPATH//://bin:}/bin`新增所有的 bin 目錄) - -以後我所有的例子都是以 mygo 作為我的 gopath 目錄 - - -## 程式碼目錄結構規劃 -GOPATH 下的 src 目錄就是接下來開發程式的主要目錄,所有的原始碼都是放在這個目錄下面,那麼一般我們的做法就是一個目錄一個專案,例如: $GOPATH/src/mymath 表示 mymath 這個套件或者可執行應用,這個根據 package 是 main 還是其他來決定,main 的話就是可執行應用,其他的話就是套件,這個會在後續詳細介紹 package。 - - -所以當建立應用或者一個程式碼套件時都是在 src 目錄下建立一個資料夾,資料夾名稱一般是程式碼套件名稱,當然也允許多階層目錄,例如在 src 下面建立了目錄$GOPATH/src/github.com/astaxie/beedb 那麼這個套件路徑就是"github.com/astaxie/beedb",套件名稱是最後一個目錄 beedb - - -下面我就以 mymath 為例來講述如何編寫套件,執行如下程式碼 - -```sh -cd $GOPATH/src -mkdir mymath -``` - -建立檔案 sqrt.go,內容如下 -```go -// $GOPATH/src/mymath/sqrt.go 原始碼如下: -package mymath - -func Sqrt(x float64) float64 { - z := 0.0 - for i := 0; i < 1000; i++ { - z -= (z*z - x) / (2 * x) - } - return z -} -``` -這樣我的套件目錄和程式碼已經建立完畢,注意:一般建議 package 的名稱和目錄名保持一致 - -## 編譯應用 -上面我們已經建立了自己的套件,如何進行編譯安裝呢?有兩種方式可以進行安裝 - -1、只要進入對應的套件目錄,然後執行`go install`,就可以安裝了 - -2、在任意的目錄執行如下程式碼`go install mymath` - -安裝完之後,我們可以進入如下目錄 - -```sh -cd $GOPATH/pkg/${GOOS}_${GOARCH} -//可以看到如下檔案 -mymath.a -``` -這個.a 檔案是套件,那麼我們如何進行呼叫呢? - -接下來我們建立一個應用程式來呼叫這個套件 - -建立套件 mathapp - -```sh -cd $GOPATH/src -mkdir mathapp -cd mathapp -vim main.go -``` - -`$GOPATH/src/mathapp/main.go`原始碼: -```go -package main - -import ( - "mymath" - "fmt" -) - -func main() { - fmt.Printf("Hello, world. Sqrt(2) = %v\n", mymath.Sqrt(2)) -} -``` - -可以看到這個的 package 是`main`,import 裡面呼叫的套件是`mymath`,這個就是相對於`$GOPATH/src`的路徑,如果是多階層目錄,就在 import 裡面引入多階層目錄,如果你有多個 GOPATH,也是一樣,Go 會自動在多個`$GOPATH/src`中尋找。 - -如何編譯程式呢?進入該應用目錄,然後執行`go build`,那麼在該目錄下面會產生一個 mathapp 的可執行檔案 - -```sh -./mathapp -``` - -輸出如下內容 - -```sh -Hello, world. Sqrt(2) = 1.414213562373095 -``` - -如何安裝該應用,進入該目錄執行`go install`,那麼在$GOPATH/bin/下增加了一個可執行檔案 mathapp, 還記得前面我們把`$GOPATH/bin`加到我們的 PATH 裡面了,這樣可以在命令列輸入如下命令就可以執行 - -```sh -mathapp -``` - -也是輸出如下內容 - - Hello, world. Sqrt(2) = 1.414213562373095 - -這裡我們展示如何編譯和安裝一個可執行的應用,以及如何設計我們的目錄結構。 - -## 取得遠端套件 - - go 語言有一個取得遠端套件的工具就是`go get`,目前 go get 支援多數開源社群(例如:github、googlecode、bitbucket、Launchpad) - - go get github.com/astaxie/beedb - ->go get -u 參數可以自動更新套件,而且當 go get 的時候會自動取得該套件依賴的其他第三方套件 - - -透過這個命令可以取得相應的原始碼,對應的開源平臺採用不同的原始碼控制工具,例如 github 採用 git、googlecode 採用 hg,所以要想取得這些原始碼,必須先安裝相應的原始碼控制工具 - -透過上面取得的程式碼在我們本地的原始碼相應的程式碼結構如下 - - $GOPATH - src - |--github.com - |-astaxie - |-beedb - pkg - |--相應平臺 - |-github.com - |--astaxie - |beedb.a - -go get 本質上可以理解為首先第一步是透過原始碼工具 clone 程式碼到 src 下面,然後執行`go install` - -在程式碼中如何使用遠端套件,很簡單的就是和使用本地套件一樣,只要在開頭 import 相應的路徑就可以 - - import "github.com/astaxie/beedb" - -## 程式的整體結構 -透過上面建立的我本地的 mygo 的目錄結構如下所示 - - bin/ - mathapp - pkg/ - 平臺名/ 如:darwin_amd64、linux_amd64 - mymath.a - github.com/ - astaxie/ - beedb.a - src/ - mathapp - main.go - mymath/ - sqrt.go - github.com/ - astaxie/ - beedb/ - beedb.go - util.go - -從上面的結構我們可以很清晰的看到,bin 目錄下面存的是編譯之後可執行的檔案,pkg 下面存放的是套件,src 下面儲存的是應用原始碼 - - -## links - * [目錄]() - * 上一節: [安裝 Go](<01.1.md>) - * 下一節: [GO 命令](<01.3.md>) +# 1.2 GOPATH 與工作空間 + +前面我們在安裝 Go 的時候看到需要設定 GOPATH 變數,Go 從 1.1 版本到 1.7 必須設定這個變數,而且不能和 Go 的安裝目錄一樣,這個目錄用來存放 Go 原始碼,Go 的可執行檔案,以及相應的編譯之後的套件檔案。所以這個目錄下面有三個子目錄:src、bin、pkg + +從 go 1.8 開始,GOPATH 環境變數現在有一個預設值,如果它沒有被設定。 它在 Unix 上預設為$HOME/go,在 Windows 上預設為%USERPROFILE%/go。 +## GOPATH 設定 + go 命令依賴一個重要的環境變數:$GOPATH + + Windows 系統中環境變數的形式為`%GOPATH%`,本書主要使用 Unix 形式,Windows 使用者請自行替換。 + + *(注:這個不是 Go 安裝目錄。下面以筆者的工作目錄為範例,如果你想不一樣請把 GOPATH 替換成你的工作目錄。)* + + 在類別 Unix 環境下大概這樣設定: + +```sh +export GOPATH=/home/apple/mygo +``` + 為了方便,應該建立以上資料夾,並且上一行加入到 `.bashrc` 或者 `.zshrc` 或者自己的 `sh` 的配置檔案中。 + + Windows 設定如下,建立一個環境變數名稱叫做 GOPATH: + +```sh +GOPATH=c:\mygo +``` +GOPATH 允許多個目錄,當有多個目錄時,請注意分隔符,多個目錄的時候 Windows 是分號,Linux 系統是冒號,當有多個 GOPATH 時,預設會將 go get 的內容放在第一個目錄下。 + + +以上 $GOPATH 目錄約定有三個子目錄: + +- src 存放原始碼(比如:.go .c .h .s 等) +- pkg 編譯後生成的檔案(比如:.a) +- bin 編譯後生成的可執行檔案(為了方便,可以把此目錄加入到 $PATH 變數中,如果有多個 gopath,那麼使用`${GOPATH//://bin:}/bin`新增所有的 bin 目錄) + +以後我所有的例子都是以 mygo 作為我的 gopath 目錄 + + +## 程式碼目錄結構規劃 +GOPATH 下的 src 目錄就是接下來開發程式的主要目錄,所有的原始碼都是放在這個目錄下面,那麼一般我們的做法就是一個目錄一個專案,例如: $GOPATH/src/mymath 表示 mymath 這個套件或者可執行應用,這個根據 package 是 main 還是其他來決定,main 的話就是可執行應用,其他的話就是套件,這個會在後續詳細介紹 package。 + + +所以當建立應用或者一個程式碼套件時都是在 src 目錄下建立一個資料夾,資料夾名稱一般是程式碼套件名稱,當然也允許多階層目錄,例如在 src 下面建立了目錄$GOPATH/src/github.com/astaxie/beedb 那麼這個套件路徑就是"github.com/astaxie/beedb",套件名稱是最後一個目錄 beedb + + +下面我就以 mymath 為例來講述如何編寫套件,執行如下程式碼 + +```sh +cd $GOPATH/src +mkdir mymath +``` + +建立檔案 sqrt.go,內容如下 +```go +// $GOPATH/src/mymath/sqrt.go 原始碼如下: +package mymath + +func Sqrt(x float64) float64 { + z := 0.0 + for i := 0; i < 1000; i++ { + z -= (z*z - x) / (2 * x) + } + return z +} +``` +這樣我的套件目錄和程式碼已經建立完畢,注意:一般建議 package 的名稱和目錄名保持一致 + +## 編譯應用 +上面我們已經建立了自己的套件,如何進行編譯安裝呢?有兩種方式可以進行安裝 + +1、只要進入對應的套件目錄,然後執行`go install`,就可以安裝了 + +2、在任意的目錄執行如下程式碼`go install mymath` + +安裝完之後,我們可以進入如下目錄 + +```sh +cd $GOPATH/pkg/${GOOS}_${GOARCH} +//可以看到如下檔案 +mymath.a +``` +這個.a 檔案是套件,那麼我們如何進行呼叫呢? + +接下來我們建立一個應用程式來呼叫這個套件 + +建立套件 mathapp + +```sh +cd $GOPATH/src +mkdir mathapp +cd mathapp +vim main.go +``` + +`$GOPATH/src/mathapp/main.go`原始碼: +```go +package main + +import ( + "mymath" + "fmt" +) + +func main() { + fmt.Printf("Hello, world. Sqrt(2) = %v\n", mymath.Sqrt(2)) +} +``` + +可以看到這個的 package 是`main`,import 裡面呼叫的套件是`mymath`,這個就是相對於`$GOPATH/src`的路徑,如果是多階層目錄,就在 import 裡面引入多階層目錄,如果你有多個 GOPATH,也是一樣,Go 會自動在多個`$GOPATH/src`中尋找。 + +如何編譯程式呢?進入該應用目錄,然後執行`go build`,那麼在該目錄下面會產生一個 mathapp 的可執行檔案 + +```sh +./mathapp +``` + +輸出如下內容 + +```sh +Hello, world. Sqrt(2) = 1.414213562373095 +``` + +如何安裝該應用,進入該目錄執行`go install`,那麼在$GOPATH/bin/下增加了一個可執行檔案 mathapp, 還記得前面我們把`$GOPATH/bin`加到我們的 PATH 裡面了,這樣可以在命令列輸入如下命令就可以執行 + +```sh +mathapp +``` + +也是輸出如下內容 + + Hello, world. Sqrt(2) = 1.414213562373095 + +這裡我們展示如何編譯和安裝一個可執行的應用,以及如何設計我們的目錄結構。 + +## 取得遠端套件 + + go 語言有一個取得遠端套件的工具就是`go get`,目前 go get 支援多數開源社群(例如:GitHub、googlecode、bitbucket、Launchpad) + + go get github.com/astaxie/beedb + +>go get -u 參數可以自動更新套件,而且當 go get 的時候會自動取得該套件依賴的其他第三方套件 + + +透過這個命令可以取得相應的原始碼,對應的開源平臺採用不同的原始碼控制工具,例如 GitHub 採用 git、googlecode 採用 hg,所以要想取得這些原始碼,必須先安裝相應的原始碼控制工具 + +透過上面取得的程式碼在我們本地的原始碼相應的程式碼結構如下 + + $GOPATH + src + |--github.com + |-astaxie + |-beedb + pkg + |--相應平臺 + |-github.com + |--astaxie + |beedb.a + +go get 本質上可以理解為首先第一步是透過原始碼工具 clone 程式碼到 src 下面,然後執行`go install` + +在程式碼中如何使用遠端套件,很簡單的就是和使用本地套件一樣,只要在開頭 import 相應的路徑就可以 + + import "github.com/astaxie/beedb" + +## 程式的整體結構 +透過上面建立的我本地的 mygo 的目錄結構如下所示 + + bin/ + mathapp + pkg/ + 平臺名/ 如:darwin_amd64、linux_amd64 + mymath.a + github.com/ + astaxie/ + beedb.a + src/ + mathapp + main.go + mymath/ + sqrt.go + github.com/ + astaxie/ + beedb/ + beedb.go + util.go + +從上面的結構我們可以很清晰的看到,bin 目錄下面存的是編譯之後可執行的檔案,pkg 下面存放的是套件,src 下面儲存的是應用原始碼 + + +## links + * [目錄]() + * 上一節: [安裝 Go](<01.1.md>) + * 下一節: [GO 命令](<01.3.md>) diff --git a/zh-tw/01.3.md b/zh-tw/01.3.md index 2ae61098..e6e90080 100644 --- a/zh-tw/01.3.md +++ b/zh-tw/01.3.md @@ -1,211 +1,211 @@ -# 1.3 Go 命令 - -## Go 命令 - - Go 語言自帶有一套完整的命令列工具,你可以透過在命令列中執行 `go` 來檢視它們: - - ![](images/1.1.mac.png) - -圖 1.3 Go 命令顯示詳細的資訊 - - 這些命令對於我們平時編寫的程式碼非常有用,接下來就讓我們了解一些常用的命令。 - -## go build - - 這個命令主要用於編譯程式碼。在套件的編譯過程中,若有必要,會同時編譯與之相關聯的套件。 - - - 如果是普通套件,就像我們在 1.2 節中編寫的 `mymath` 套件那樣,當你執行`go build`之後,它不會產生任何檔案。如果你需要在`$GOPATH/pkg`下產生相應的檔案,那就得執行`go install`。 - - - 如果是 `main` 套件,當你執行`go build`之後,它就會在當前目錄下產生一個可執行檔案。如果你需要在`$GOPATH/bin`下產生相應的檔案,需要執行`go install`,或者使用`go build -o 路徑/a.exe`。 - - - 如果某個專案資料夾下有多個檔案,而你只想編譯某個檔案,就可在`go build`之後加上檔名,例如`go build a.go`;`go build`命令預設會編譯當前目錄下的所有 go 檔案。 - - - 你也可以指定編譯輸出的檔名。例如 1.2 節中的 `mathapp` 應用,我們可以指定`go build -o astaxie.exe`,預設情況是你的 package 名(非 main 套件),或者是第一個原始檔的檔名(main 套件)。 - - (注:實際上,package 名在 [Go 語言規範](https://golang.org/ref/spec)中指程式碼中“package”後使用的名稱,此名稱可以與資料夾名不同。預設產生的可執行檔名是資料夾名。) - - - go build 會忽略目錄下以“_”或“.”開頭的 go 檔案。 - - - 如果你的原始碼針對不同的作業系統需要不同的處理,那麼你可以根據不同的作業系統字尾來命名檔案。例如有一個讀取陣列的程式,它對於不同的作業系統可能有如下幾個原始檔: - - array_linux.go - array_darwin.go - array_windows.go - array_freebsd.go - - `go build`的時候會選擇性地編譯以系統名結尾的檔案(Linux、Darwin、Windows、Freebsd)。例如 Linux 系統下面編譯只會選擇 array_linux.go 檔案,其它系統命名字尾檔案全部忽略。 - -參數的介紹 - -- `-o` 指定輸出的檔名,可以帶上路徑,例如 `go build -o a/b/c` -- `-i` 安裝相應的套件,編譯+`go install` -- `-a` 更新全部已經是最新的套件的,但是對標準套件不適用 -- `-n` 把需要執行的編譯命令顯示出來,但是不執行,這樣就可以很容易的知道底層是如何執行的 -- `-p n` 指定可以並行可執行的編譯數目,預設是 CPU 數目 -- `-race` 開啟編譯的時候自動檢測資料競爭的情況,目前只支援 64 位的機器 -- `-v` 顯示出來我們正在編譯的套件名 -- `-work` 顯示出來編譯時候的臨時資料夾名稱,並且如果已經存在的話就不要刪除 -- `-x` 顯示出來執行的命令,其實就是和`-n`的結果類似,只是這個會執行 -- `-ccflags 'arg list'` 傳遞參數給 5c, 6c, 8c 呼叫 -- `-compiler name` 指定相應的編譯器,gccgo 還是 gc - -- `-gccgoflags 'arg list'` 傳遞參數給 gccgo 編譯連線呼叫 -- `-gcflags 'arg list'` 傳遞參數給 5g, 6g, 8g 呼叫 -- `-installsuffix suffix` 為了和預設的安裝套件區別開來,採用這個字首來重新安裝那些依賴的套件,`-race`的時候預設已經是`-installsuffix race`,大家可以透過`-n`命令來驗證 -- `-ldflags 'flag list'` 傳遞參數給 5l, 6l, 8l 呼叫 -- `-tags 'tag list'` 設定在編譯的時候可以適配的那些 tag,詳細的 tag 限制參考裡面的 [Build Constraints](http://golang.org/pkg/go/build/) - -## go clean - - 這個命令是用來移除當前原始碼套件和關聯原始碼套件裡面編譯產生的檔案。這些檔案包括 - - _obj/ 舊的 object 目錄,由 Makefiles 遺留 - _test/ 舊的 test 目錄,由 Makefiles 遺留 - _testmain.go 舊的 gotest 檔案,由 Makefiles 遺留 - test.out 舊的 test 記錄,由 Makefiles 遺留 - build.out 舊的 test 記錄,由 Makefiles 遺留 - *.[568ao] object 檔案,由 Makefiles 遺留 - - DIR(.exe) 由 go build 產生 - DIR.test(.exe) 由 go test -c 產生 - MAINFILE(.exe) 由 go build MAINFILE.go 產生 - *.so 由 SWIG 產生 - - 我一般都是利用這個命令清除編譯檔案,然後 github 提交原始碼,在本機測試的時候這些編譯檔案都是和系統相關的,但是對於原始碼管理來說沒必要。 - - $ go clean -i -n - cd /Users/astaxie/develop/gopath/src/mathapp - rm -f mathapp mathapp.exe mathapp.test mathapp.test.exe app app.exe - rm -f /Users/astaxie/develop/gopath/bin/mathapp - -參數介紹 - -- `-i` 清除關聯的安裝的套件和可執行檔案,也就是透過 go install 安裝的檔案 -- `-n` 把需要執行的清除命令顯示出來,但是不執行,這樣就可以很容易的知道底層是如何執行的 -- `-r` 迴圈的清除在 import 中引入的套件 - -- `-x` 顯示出來執行的詳細命令,其實就是`-n`列印的執行版本 - -## go fmt - - 有過 C/C++經驗的讀者會知道,一些人經常為程式碼採取 K&R 風格還是 ANSI 風格而爭論不休。在 go 中,程式碼則有標準的風格。由於之前已經有的一些習慣或其它的原因我們常將程式碼寫成 ANSI 風格或者其它更合適自己的格式,這將為人們在閱讀別人的程式碼時新增不必要的負擔,所以 go 強制了程式碼格式(比如左大括號必須放在行尾),不按照此格式的程式碼將不能編譯透過,為了減少浪費在排版上的時間,go 工具集中提供了一個`go fmt`命令 它可以幫你格式化你寫好的程式碼檔案,使你寫程式碼的時候不需要關心格式,你只需要在寫完之後執行`go fmt <檔名>.go`,你的程式碼就被修改成了標準格式,但是我平常很少用到這個命令,因為開發工具裡面一般都帶了儲存時候自動格式化功能,這個功能其實在底層就是呼叫了`go fmt`。接下來的一節我將講述兩個工具,這兩個工具都自帶了儲存檔案時自動化`go fmt`功能。 - -使用 go fmt 命令,其實是呼叫了 gofmt,而且需要參數-w,否則格式化結果不會寫入檔案。gofmt -w -l src,可以格式化整個專案。 - -所以 go fmt 是 gofmt 的上層一個封裝命令,如果想要更多的自訂格式化,可以參考 [gofmt](http://golang.org/cmd/gofmt/) - -gofmt 的參數介紹 - -- `-l` 顯示那些需要格式化的檔案 -- `-w` 把改寫後的內容直接寫入到檔案中,而不是作為結果列印到標準輸出。 -- `-r` 新增形如“a[b:len(a)] -> a[b:]”的重寫規則,方便我們做批量替換 -- `-s` 簡化檔案中的程式碼 -- `-d` 顯示格式化前後的 diff 而不是寫入檔案,預設是 false - -- `-e` 列印所有的語法錯誤到標準輸出。如果不使用此標記,則只會列印不同行的前 10 個錯誤。 -- `-cpuprofile` 支援除錯模式,寫入相應的 cpufile 到指定的檔案 - -## go get - - 這個命令是用來動態取得遠端程式碼套件的,目前支援的有 BitBucket、GitHub、Google Code 和 Launchpad。這個命令在內部實際上分成了兩步操作:第一步是下載原始碼套件,第二步是執行`go install`。下載原始碼套件的 go 工具會自動根據不同的域名呼叫不同的原始碼工具,對應關係如下: - - BitBucket (Mercurial Git) - GitHub (Git) - Google Code Project Hosting (Git, Mercurial, Subversion) - Launchpad (Bazaar) - - 所以為了`go get` 能正常工作,你必須確保安裝了合適的原始碼管理工具,並同時把這些命令加入你的 PATH 中。其實`go get`支援自訂域名的功能,具體參見`go help remote`。 - -參數介紹: - -- `-d` 只下載不安裝 -- `-f` 只有在你包含了`-u`參數的時候才有效,不讓`-u`去驗證 import 中的每一個都已經取得了,這對於本地 fork 的套件特別有用 -- `-fix` 在取得原始碼之後先執行 fix,然後再去做其他的事情 -- `-t` 同時也下載需要為執行測試所需要的套件 - -- `-u` 強制使用網路去更新套件和它的相依套件 -- `-v` 顯示執行的命令 - -## go install - - 這個命令在內部實際上分成了兩步操作:第一步是產生結果檔案(可執行檔案或者.a 套件),第二步會把編譯好的結果移到`$GOPATH/pkg`或者`$GOPATH/bin`。 - -參數支援`go build`的編譯參數。大家只要記住一個參數`-v`就好了,這個隨時隨地的可以檢視底層的執行資訊。 - -## go test - - 執行這個命令,會自動讀取原始碼目錄下面名為`*_test.go`的檔案,產生並執行測試用的可執行檔案。輸出的資訊類似 - - ok archive/tar 0.011s - FAIL archive/zip 0.022s - ok compress/gzip 0.033s - ... - - 預設的情況下,不需要任何的參數,它會自動把你原始碼套件下面所有 test 檔案測試完畢,當然你也可以帶上參數,詳情請參考`go help testflag` - -這裡我介紹幾個我們常用的參數: - -- `-bench regexp` 執行相應的 benchmarks,例如 `-bench=.` -- `-cover` 開啟測試覆蓋率 -- `-run regexp` 只執行 regexp 匹配的函式,例如 `-run=Array` 那麼就執行包含有 Array 開頭的函式 -- `-v` 顯示測試的詳細命令 - -## go tool -`go tool`下面下載聚集了很多命令,這裡我們只介紹兩個,fix 和 vet - - -- `go tool fix .` 用來修復以前老版本的程式碼到新版本,例如 go1 之前老版本的程式碼轉化到 go1,例如 API 的變化 -- `go tool vet directory|files` 用來分析當前目錄的程式碼是否都是正確的程式碼,例如是不是呼叫 fmt.Printf 裡面的參數不正確,例如函式裡面提前 return 了然後出現了無用程式碼之類別的。 - -## go generate - -這個命令是從 Go1.4 開始才設計的,用於在編譯前自動化產生某類別程式碼。`go generate`和`go build`是完全不一樣的命令,透過分析原始碼中特殊的註釋,然後執行相應的命令。這些命令都是很明確的,沒有任何的依賴在裡面。而且大家在用這個之前心裡面一定要有一個觀念,這個 `go generate` 是給你用的,不是給使用你這個套件的人用的,主要是方便你自動產生一些程式碼。 - -這裡我們來舉一個簡單的例子,例如我們經常會使用 `yacc` 來產生程式碼,那麼我們常用這樣的命令: - - go tool yacc -o gopher.go -p parser gopher.y - --o 指定了輸出的檔名, -p 指定了 package 的名稱,這是一個單獨的命令,如果我們想讓`go generate`來觸發這個命令,那麼就可以在當前目錄的任意一個`xxx.go`檔案裡面的任意位置增加一行如下的註釋: - - //go:generate go tool yacc -o gopher.go -p parser gopher.y - -這裡我們注意了,`//go:generate`是沒有任何空格的,這其實就是一個固定的格式,在掃描原始碼檔案的時候就是根據這個來判斷的。 - -所以我們可以透過如下的命令來產生,編譯,測試。如果`gopher.y`檔案有修改,那麼就重新執行`go generate`重新產生檔案就好。 - - $ go generate - $ go build - $ go test - - -## godoc - -在 Go1.2 版本之前還支援`go doc`命令,但是之後全部移到了 godoc 這個命令下,需要這樣安裝`go get golang.org/x/tools/cmd/godoc` - - 很多人說 go 不需要任何的第三方文件,例如 chm 手冊之類別的(其實我已經做了一個了,[chm 手冊](https://github.com/astaxie/godoc)),因為它內部就有一個很強大的文件工具。 - - 如何檢視相應 package 的文件呢? - 例如 builtin 套件,那麼執行`godoc builtin` - 如果是 http 套件,那麼執行`godoc net/http` - 檢視某一個套件裡面的函式,那麼執行`godoc fmt Printf` - 也可以檢視相應的程式碼,執行`godoc -src fmt Printf` - - 透過命令在命令列執行 godoc -http=:埠號 比如`godoc -http=:8080`。然後在瀏覽器中開啟`127.0.0.1:8080`,你將會看到一個 golang.org 的本地 copy 版本,透過它你可以查詢 pkg 文件等其它內容。如果你設定了 GOPATH,在 pkg 分類下,不但會列出標準套件的文件,還會列出你本地 `GOPATH` 中所有專案的相關文件,這對於經常被牆的使用者來說是一個不錯的選擇。 - -## 其它命令 - - go 還提供了其它很多的工具,例如下面的這些工具 - - go version 檢視 go 當前的版本 - go env 檢視當前 go 的環境變數 - go list 列出當前全部安裝的 package - - go run 編譯並執行 Go 程式 - -以上這些工具還有很多參數沒有一一介紹,使用者可以使用`go help 命令 ` 取得更詳細的幫助資訊。 - - -## links - * [目錄]() - * 上一節: [GOPATH 與工作空間](<01.2.md>) - * 下一節: [Go 開發工具](<01.4.md>) +# 1.3 Go 命令 + +## Go 命令 + + Go 語言自帶有一套完整的命令列工具,你可以透過在命令列中執行 `go` 來檢視它們: + + ![](images/1.1.mac.png) + +圖 1.3 Go 命令顯示詳細的資訊 + + 這些命令對於我們平時編寫的程式碼非常有用,接下來就讓我們了解一些常用的命令。 + +## go build + + 這個命令主要用於編譯程式碼。在套件的編譯過程中,若有必要,會同時編譯與之相關聯的套件。 + + - 如果是普通套件,就像我們在 1.2 節中編寫的 `mymath` 套件那樣,當你執行`go build`之後,它不會產生任何檔案。如果你需要在`$GOPATH/pkg`下產生相應的檔案,那就得執行`go install`。 + + - 如果是 `main` 套件,當你執行`go build`之後,它就會在當前目錄下產生一個可執行檔案。如果你需要在`$GOPATH/bin`下產生相應的檔案,需要執行`go install`,或者使用`go build -o 路徑/a.exe`。 + + - 如果某個專案資料夾下有多個檔案,而你只想編譯某個檔案,就可在`go build`之後加上檔名,例如`go build a.go`;`go build`命令預設會編譯當前目錄下的所有 go 檔案。 + + - 你也可以指定編譯輸出的檔名。例如 1.2 節中的 `mathapp` 應用,我們可以指定`go build -o astaxie.exe`,預設情況是你的 package 名(非 main 套件),或者是第一個原始檔的檔名(main 套件)。 + + (注:實際上,package 名在 [Go 語言規範](https://golang.org/ref/spec)中指程式碼中“package”後使用的名稱,此名稱可以與資料夾名不同。預設產生的可執行檔名是資料夾名。) + + - go build 會忽略目錄下以“_”或“.”開頭的 go 檔案。 + + - 如果你的原始碼針對不同的作業系統需要不同的處理,那麼你可以根據不同的作業系統字尾來命名檔案。例如有一個讀取陣列的程式,它對於不同的作業系統可能有如下幾個原始檔: + + array_linux.go + array_darwin.go + array_windows.go + array_freebsd.go + + `go build`的時候會選擇性地編譯以系統名結尾的檔案(Linux、Darwin、Windows、Freebsd)。例如 Linux 系統下面編譯只會選擇 array_linux.go 檔案,其它系統命名字尾檔案全部忽略。 + +參數的介紹 + +- `-o` 指定輸出的檔名,可以帶上路徑,例如 `go build -o a/b/c` +- `-i` 安裝相應的套件,編譯+`go install` +- `-a` 更新全部已經是最新的套件的,但是對標準套件不適用 +- `-n` 把需要執行的編譯命令顯示出來,但是不執行,這樣就可以很容易的知道底層是如何執行的 +- `-p n` 指定可以並行可執行的編譯數目,預設是 CPU 數目 +- `-race` 開啟編譯的時候自動檢測資料競爭的情況,目前只支援 64 位的機器 +- `-v` 顯示出來我們正在編譯的套件名 +- `-work` 顯示出來編譯時候的臨時資料夾名稱,並且如果已經存在的話就不要刪除 +- `-x` 顯示出來執行的命令,其實就是和`-n`的結果類似,只是這個會執行 +- `-ccflags 'arg list'` 傳遞參數給 5c, 6c, 8c 呼叫 +- `-compiler name` 指定相應的編譯器,gccgo 還是 gc + +- `-gccgoflags 'arg list'` 傳遞參數給 gccgo 編譯連線呼叫 +- `-gcflags 'arg list'` 傳遞參數給 5g, 6g, 8g 呼叫 +- `-installsuffix suffix` 為了和預設的安裝套件區別開來,採用這個字首來重新安裝那些依賴的套件,`-race`的時候預設已經是`-installsuffix race`,大家可以透過`-n`命令來驗證 +- `-ldflags 'flag list'` 傳遞參數給 5l, 6l, 8l 呼叫 +- `-tags 'tag list'` 設定在編譯的時候可以適配的那些 tag,詳細的 tag 限制參考裡面的 [Build Constraints](http://golang.org/pkg/go/build/) + +## go clean + + 這個命令是用來移除當前原始碼套件和關聯原始碼套件裡面編譯產生的檔案。這些檔案包括 + + _obj/ 舊的 object 目錄,由 Makefiles 遺留 + _test/ 舊的 test 目錄,由 Makefiles 遺留 + _testmain.go 舊的 gotest 檔案,由 Makefiles 遺留 + test.out 舊的 test 記錄,由 Makefiles 遺留 + build.out 舊的 test 記錄,由 Makefiles 遺留 + *.[568ao] object 檔案,由 Makefiles 遺留 + + DIR(.exe) 由 go build 產生 + DIR.test(.exe) 由 go test -c 產生 + MAINFILE(.exe) 由 go build MAINFILE.go 產生 + *.so 由 SWIG 產生 + + 我一般都是利用這個命令清除編譯檔案,然後 GitHub 提交原始碼,在本機測試的時候這些編譯檔案都是和系統相關的,但是對於原始碼管理來說沒必要。 + + $ go clean -i -n + cd /Users/astaxie/develop/gopath/src/mathapp + rm -f mathapp mathapp.exe mathapp.test mathapp.test.exe app app.exe + rm -f /Users/astaxie/develop/gopath/bin/mathapp + +參數介紹 + +- `-i` 清除關聯的安裝的套件和可執行檔案,也就是透過 go install 安裝的檔案 +- `-n` 把需要執行的清除命令顯示出來,但是不執行,這樣就可以很容易的知道底層是如何執行的 +- `-r` 迴圈的清除在 import 中引入的套件 + +- `-x` 顯示出來執行的詳細命令,其實就是`-n`列印的執行版本 + +## go fmt + + 有過 C/C++經驗的讀者會知道,一些人經常為程式碼採取 K&R 風格還是 ANSI 風格而爭論不休。在 go 中,程式碼則有標準的風格。由於之前已經有的一些習慣或其它的原因我們常將程式碼寫成 ANSI 風格或者其它更合適自己的格式,這將為人們在閱讀別人的程式碼時新增不必要的負擔,所以 go 強制了程式碼格式(比如左大括號必須放在行尾),不按照此格式的程式碼將不能編譯透過,為了減少浪費在排版上的時間,go 工具集中提供了一個`go fmt`命令 它可以幫你格式化你寫好的程式碼檔案,使你寫程式碼的時候不需要關心格式,你只需要在寫完之後執行`go fmt <檔名>.go`,你的程式碼就被修改成了標準格式,但是我平常很少用到這個命令,因為開發工具裡面一般都帶了儲存時候自動格式化功能,這個功能其實在底層就是呼叫了`go fmt`。接下來的一節我將講述兩個工具,這兩個工具都自帶了儲存檔案時自動化`go fmt`功能。 + +使用 go fmt 命令,其實是呼叫了 gofmt,而且需要參數-w,否則格式化結果不會寫入檔案。gofmt -w -l src,可以格式化整個專案。 + +所以 go fmt 是 gofmt 的上層一個封裝命令,如果想要更多的自訂格式化,可以參考 [gofmt](http://golang.org/cmd/gofmt/) + +gofmt 的參數介紹 + +- `-l` 顯示那些需要格式化的檔案 +- `-w` 把改寫後的內容直接寫入到檔案中,而不是作為結果列印到標準輸出。 +- `-r` 新增形如“a[b:len(a)] -> a[b:]”的重寫規則,方便我們做批量替換 +- `-s` 簡化檔案中的程式碼 +- `-d` 顯示格式化前後的 diff 而不是寫入檔案,預設是 false + +- `-e` 列印所有的語法錯誤到標準輸出。如果不使用此標記,則只會列印不同行的前 10 個錯誤。 +- `-cpuprofile` 支援除錯模式,寫入相應的 cpufile 到指定的檔案 + +## go get + + 這個命令是用來動態取得遠端程式碼套件的,目前支援的有 BitBucket、GitHub、Google Code 和 Launchpad。這個命令在內部實際上分成了兩步操作:第一步是下載原始碼套件,第二步是執行`go install`。下載原始碼套件的 go 工具會自動根據不同的域名呼叫不同的原始碼工具,對應關係如下: + + BitBucket (Mercurial Git) + GitHub (Git) + Google Code Project Hosting (Git, Mercurial, Subversion) + Launchpad (Bazaar) + + 所以為了`go get` 能正常工作,你必須確保安裝了合適的原始碼管理工具,並同時把這些命令加入你的 PATH 中。其實`go get`支援自訂域名的功能,具體參見`go help remote`。 + +參數介紹: + +- `-d` 只下載不安裝 +- `-f` 只有在你包含了`-u`參數的時候才有效,不讓`-u`去驗證 import 中的每一個都已經取得了,這對於本地 fork 的套件特別有用 +- `-fix` 在取得原始碼之後先執行 fix,然後再去做其他的事情 +- `-t` 同時也下載需要為執行測試所需要的套件 + +- `-u` 強制使用網路去更新套件和它的相依套件 +- `-v` 顯示執行的命令 + +## go install + + 這個命令在內部實際上分成了兩步操作:第一步是產生結果檔案(可執行檔案或者.a 套件),第二步會把編譯好的結果移到`$GOPATH/pkg`或者`$GOPATH/bin`。 + +參數支援`go build`的編譯參數。大家只要記住一個參數`-v`就好了,這個隨時隨地的可以檢視底層的執行資訊。 + +## go test + + 執行這個命令,會自動讀取原始碼目錄下面名為`*_test.go`的檔案,產生並執行測試用的可執行檔案。輸出的資訊類似 + + ok archive/tar 0.011s + FAIL archive/zip 0.022s + ok compress/gzip 0.033s + ... + + 預設的情況下,不需要任何的參數,它會自動把你原始碼套件下面所有 test 檔案測試完畢,當然你也可以帶上參數,詳情請參考`go help testflag` + +這裡我介紹幾個我們常用的參數: + +- `-bench regexp` 執行相應的 benchmarks,例如 `-bench=.` +- `-cover` 開啟測試覆蓋率 +- `-run regexp` 只執行 regexp 匹配的函式,例如 `-run=Array` 那麼就執行包含有 Array 開頭的函式 +- `-v` 顯示測試的詳細命令 + +## go tool +`go tool`下面下載聚集了很多命令,這裡我們只介紹兩個,fix 和 vet + + +- `go tool fix .` 用來修復以前老版本的程式碼到新版本,例如 go1 之前老版本的程式碼轉化到 go1,例如 API 的變化 +- `go tool vet directory|files` 用來分析當前目錄的程式碼是否都是正確的程式碼,例如是不是呼叫 fmt.Printf 裡面的參數不正確,例如函式裡面提前 return 了然後出現了無用程式碼之類別的。 + +## go generate + +這個命令是從 Go1.4 開始才設計的,用於在編譯前自動化產生某類別程式碼。`go generate`和`go build`是完全不一樣的命令,透過分析原始碼中特殊的註釋,然後執行相應的命令。這些命令都是很明確的,沒有任何的依賴在裡面。而且大家在用這個之前心裡面一定要有一個觀念,這個 `go generate` 是給你用的,不是給使用你這個套件的人用的,主要是方便你自動產生一些程式碼。 + +這裡我們來舉一個簡單的例子,例如我們經常會使用 `yacc` 來產生程式碼,那麼我們常用這樣的命令: + + go tool yacc -o gopher.go -p parser gopher.y + +-o 指定了輸出的檔名, -p 指定了 package 的名稱,這是一個單獨的命令,如果我們想讓`go generate`來觸發這個命令,那麼就可以在當前目錄的任意一個`xxx.go`檔案裡面的任意位置增加一行如下的註釋: + + //go:generate go tool yacc -o gopher.go -p parser gopher.y + +這裡我們注意了,`//go:generate`是沒有任何空格的,這其實就是一個固定的格式,在掃描原始碼檔案的時候就是根據這個來判斷的。 + +所以我們可以透過如下的命令來產生,編譯,測試。如果`gopher.y`檔案有修改,那麼就重新執行`go generate`重新產生檔案就好。 + + $ go generate + $ go build + $ go test + + +## godoc + +在 Go1.2 版本之前還支援`go doc`命令,但是之後全部移到了 godoc 這個命令下,需要這樣安裝`go get golang.org/x/tools/cmd/godoc` + + 很多人說 go 不需要任何的第三方文件,例如 chm 手冊之類別的(其實我已經做了一個了,[chm 手冊](https://github.com/astaxie/godoc)),因為它內部就有一個很強大的文件工具。 + + 如何檢視相應 package 的文件呢? + 例如 builtin 套件,那麼執行`godoc builtin` + 如果是 http 套件,那麼執行`godoc net/http` + 檢視某一個套件裡面的函式,那麼執行`godoc fmt Printf` + 也可以檢視相應的程式碼,執行`godoc -src fmt Printf` + + 透過命令在命令列執行 godoc -http=:埠號 比如`godoc -http=:8080`。然後在瀏覽器中開啟`127.0.0.1:8080`,你將會看到一個 golang.org 的本地 copy 版本,透過它你可以查詢 pkg 文件等其它內容。如果你設定了 GOPATH,在 pkg 分類下,不但會列出標準套件的文件,還會列出你本地 `GOPATH` 中所有專案的相關文件,這對於經常被牆的使用者來說是一個不錯的選擇。 + +## 其它命令 + + go 還提供了其它很多的工具,例如下面的這些工具 + + go version 檢視 go 當前的版本 + go env 檢視當前 go 的環境變數 + go list 列出當前全部安裝的 package + + go run 編譯並執行 Go 程式 + +以上這些工具還有很多參數沒有一一介紹,使用者可以使用`go help 命令 ` 取得更詳細的幫助資訊。 + + +## links + * [目錄]() + * 上一節: [GOPATH 與工作空間](<01.2.md>) + * 下一節: [Go 開發工具](<01.4.md>) diff --git a/zh-tw/01.4.md b/zh-tw/01.4.md index 8b819fbf..68b53d8e 100644 --- a/zh-tw/01.4.md +++ b/zh-tw/01.4.md @@ -1,644 +1,644 @@ -# 1.4 Go 開發工具 - -本節我將介紹幾個開發工具,它們都具有自動化提示,自動化 fmt 功能。因為它們都是跨平臺的,所以安裝步驟之類別的都是通用的。 - -## LiteIDE - - LiteIDE 是一款專門為 Go 語言開發的跨平臺輕量級整合開發環境(IDE),由 visualfc 編寫。 - - ![](images/1.4.liteide.png) - -圖 1.4 LiteIDE 主介面 - -**LiteIDE 主要特點:** - -* 支援主流作業系統 - * Windows - * Linux - * MacOS X -* Go 編譯環境管理和切換 - * 管理和切換多個 Go 編譯環境 - * 支援 Go 語言交叉編譯 -* 與 Go 標準一致的專案管理方式 - * 基於 GOPATH 的套件瀏覽器 - * 基於 GOPATH 的編譯系統 - * 基於 GOPATH 的 Api 文件檢索 -* Go 語言的編輯支援 - * 類別瀏覽器和大綱顯示 - * Gocode(程式碼自動完成工具)的完美支援 - * Go 語言文件檢視和 Api 快速檢索 - * 程式碼表達式資訊顯示`F1` - * 原始碼定義跳轉支援`F2` - * Gdb 斷點和除錯支援 - * gofmt 自動格式化支援 -* 其他特徵 - * 支援多國語言介面顯示 - * 完全外掛體系結構 - * 支援編輯器配色方案 - * 基於 Kate 的語法顯示支援 - * 基於全文的單詞自動完成 - * 支援鍵盤快捷鍵繫結方案 - * Markdown 文件編輯支援 - * 即時預覽和同步顯示 - * 自訂 CSS 顯示 - * 可匯出 HTML 和 PDF 文件 - * 批量轉換/合併為 HTML/PDF 文件 - -**LiteIDE 安裝配置** - -* LiteIDE 安裝 - * 下載地址 - * 原始碼地址 - - 首先安裝好 Go 語言環境,然後根據作業系統下載 LiteIDE 對應的壓縮檔案直接解壓即可使用。 - -* 編譯環境設定 - - 根據自身系統要求切換和配置 LiteIDE 當前使用的環境變數。 - - 以 Windows 作業系統,64 位 Go 語言為例, - 工具欄的環境配置中選擇 win64,點 ` 編輯環境`,進入 LiteIDE 編輯 win64.env 檔案 - - GOROOT=c:\go - GOBIN= - GOARCH=amd64 - GOOS=windows - CGO_ENABLED=1 - - PATH=%GOBIN%;%GOROOT%\bin;%PATH% - 。。。 - - 將其中的 `GOROOT=c:\go` 修改為當前 Go 安裝路徑,存檔即可,如果有 MinGW64,可以將 `c:\MinGW64\bin` 加入 PATH 中以便 go 呼叫 gcc 支援 CGO 編譯。 - - 以 Linux 作業系統,64 位 Go 語言為例, - 工具欄的環境配置中選擇 linux64,點 ` 編輯環境`,進入 LiteIDE 編輯 linux64.env 檔案 - - GOROOT=$HOME/go - GOBIN= - GOARCH=amd64 - GOOS=linux - CGO_ENABLED=1 - - PATH=$GOBIN:$GOROOT/bin:$PATH - 。。。 - - 將其中的`GOROOT=$HOME/go`修改為當前 Go 安裝路徑,存檔即可。 - -* GOPATH 設定 - - Go 語言的工具鏈使用 GOPATH 設定,是 Go 語言開發的專案路徑列表,在命令列中輸入(在 LiteIDE 中也可以`Ctrl+,`直接輸入)`go help gopath`快速檢視 GOPATH 文件。 - - 在 LiteIDE 中可以方便的檢視和設定 GOPATH。透過 ` 選單-檢視-GOPATH`設定,可以檢視系統中已存在的 GOPATH 列表, - 同時可根據需要新增專案目錄到自訂 GOPATH 列表中。 - -## Sublime Text - - 這裡將介紹 Sublime Text 3(以下簡稱 Sublime)+ GoSublime + gocode 的組合,那麼為什麼選擇這個組合呢? - - - 自動化提示程式碼,如下圖所示 - - ![](images/1.4.sublime1.png) - - 圖 1.5 sublime 自動化提示介面 - - - 儲存的時候自動格式化程式碼,讓您編寫的程式碼更加美觀,符合 Go 的標準。 - - 支援專案管理 - - ![](images/1.4.sublime2.png) - - 圖 1.6 sublime 專案管理介面 - - - 支援語法高亮 - - Sublime Text 3 可免費使用,只是儲存次數達到一定數量之後就會提示是否購買,點選取消繼續用,和正式註冊版本沒有任何區別。 - - -接下來就開始講如何安裝,下載 [Sublime](http://www.sublimetext.com/) - - 根據自己相應的系統下載相應的版本,然後開啟 Sublime,對於不熟悉 Sublime 的同學可以先看一下這篇文章[Sublime Text 全程指南](http://blog.jobbole.com/88648/)或者[sublime text3 入門課程](http://blog.csdn.net/sam976/article/details/52076271) - - 1. 開啟之後安裝 Package Control:Ctrl+` 開啟命令列,執行如下程式碼: - - 適用於 Sublime Text 3: - -```Go -import urllib.request,os;pf='Package Control.sublime-package';ipp=sublime.installed_packages_path();urllib.request.install_opener(urllib.request.build_opener(urllib.request.ProxyHandler()));open(os.path.join(ipp,pf),'wb').write(urllib.request.urlopen('http://sublime.wbond.net/'+pf.replace(' ','%20')).read()) -``` - 適用於 Sublime Text 2: - -```Go -import urllib2,os;pf='Package Control.sublime-package';ipp=sublime.installed_packages_path();os.makedirs(ipp)ifnotos.path.exists(ipp)elseNone;urllib2.install_opener(urllib2.build_opener(urllib2.ProxyHandler()));open(os.path.join(ipp,pf),'wb').write(urllib2.urlopen('http://sublime.wbond.net/'+pf.replace(' ','%20')).read());print('Please restart Sublime Text to finish installation') -``` - - 這個時候重啟一下 Sublime,可以發現在在選單欄多了一個如下的節目,說明 Package Control 已經安裝成功了。 - - ![](images/1.4.sublime3.png) - - 圖 1.7 sublime 套件管理 - - - 2. 安裝完之後就可以安裝 Sublime 的外掛了。需安裝 GoSublime、SidebarEnhancements 和 Go Build,安裝外掛之後記得重啟 Sublime 生效,Ctrl+Shift+p 開啟 Package Controll 輸入`pcip`(即“Package Control: Install Package”的縮寫)。 - - 這個時候看左下角顯示正在讀取套件資料,完成之後出現如下介面 - - ![](images/1.4.sublime4.png) - - 圖 1.8 sublime 安裝外掛介面 - - 這個時候輸入 GoSublime,按確定就開始安裝了。同理應用於 SidebarEnhancements 和 Go Build。 - - 3. 安裝 [gocode](https://github.com/nsf/gocode/) - - go get -u github.com/nsf/gocode - - gocode 將會安裝在預設`$GOBIN` - - 另外建議安裝 gotests(產生測試程式碼): - - - 先在 sublime 安裝 gotests 外掛,再執行: - - -```Go -go get -u -v github.com/cweill/gotests/... -``` - - 3. 驗證是否安裝成功,你可以開啟 Sublime,開啟 main.go,看看語法是不是高亮了,輸入 `import` 是不是自動化提示了,`import "fmt"`之後,輸入`fmt.`是不是自動化提示有函數了。 - - 如果已經出現這個提示,那說明你已經安裝完成了,並且完成了自動提示。 - - 如果沒有出現這樣的提示,一般就是你的`$PATH`沒有配置正確。你可以開啟終端,輸入 gocode,是不是能夠正確執行,如果不行就說明`$PATH`沒有配置正確。 - (針對 XP)有時候在終端能執行成功,但 sublime 無提示或者編譯解碼錯誤,請安裝 sublime text3 和 convert utf8 外掛試一試 - - 4. MacOS 下已經設定了$GOROOT, $GOPATH, $GOBIN,還是沒有自動提示怎麼辦。 - - 請在 sublime 中使用 command + 9, 然後輸入 env 檢查$PATH, GOROOT, $GOPATH, $GOBIN 等變數, 如果沒有請採用下面的方法。 - - 首先建立下面的連線, 然後從 Terminal 中直接啟動 sublime - - - ln -s /Applications/Sublime\ Text\ 2.app/Contents/SharedSupport/bin/subl /usr/local/bin/sublime - - -## Visual Studio Code - -VSCode 是微軟基於 Electron 和 web 技術建構的開源編輯器, 是一款很強大的編輯器。開源地址:https://github.com/Microsoft/VSCode - -1、安裝 Visual Studio Code 最新版 - -官方網站:https://code.visualstudio.com/ -下載 Visual Studio Code 最新版,安裝過程略。 - -2、安裝 Go 外掛 - -點選右邊的 Extensions 圖示 -搜尋 Go 外掛 -在外掛列表中,選擇 Go,進行安裝,安裝之後,系統會提示重啟 Visual Studio Code。 - -建議把自動儲存功能開啟。開啟方法為:選擇選單 File,點選 Auto save。 - -VSCode 程式碼設定可用於 Go 擴充套件。這些都可以在使用者的喜好來設定或工作區設定(.VSCode/settings.json)。 - -開啟首選項-使用者設定 settings.json: - -```Go - -{ - "go.buildOnSave": true, - "go.lintOnSave": true, - "go.vetOnSave": true, - "go.buildFlags": [], - "go.lintFlags": [], - "go.vetFlags": [], - "go.coverOnSave": false, - "go.useCodeSnippetsOnFunctionSuggest": false, - "go.formatOnSave": true, - //goimports - "go.formatTool": "goreturns", - "go.goroot": "",//你的 Goroot - - "go.gopath": "",//你的 Gopath - -} -``` - -接著安裝相依套件支援(網路不穩定,請直接到 Github [Golang](https://github.com/golang) 下載再移動到相關目錄): - -```Go -go get -u -v github.com/nsf/gocode -go get -u -v github.com/rogpeppe/godef -go get -u -v github.com/zmb3/gogetdoc -go get -u -v github.com/golang/lint/golint -go get -u -v github.com/lukehoban/go-outline -go get -u -v sourcegraph.com/sqs/goreturns -go get -u -v golang.org/x/tools/cmd/gorename -go get -u -v github.com/tpng/gopkgs -go get -u -v github.com/newhook/go-symbols -go get -u -v golang.org/x/tools/cmd/guru -go get -u -v github.com/cweill/gotests/... -``` - -VSCode 還有一項很強大的功能就是斷點除錯,結合 [delve](https://github.com/derekparker/delve) 可以很好的進行 Go 程式碼除錯 - -```Go - -go get -v -u github.com/peterh/liner github.com/derekparker/delve/cmd/dlv - -brew install go-delve/delve/delve(mac 可選) -``` - -如果有問題再來一遍: - -```Go -go get -v -u github.com/peterh/liner github.com/derekparker/delve/cmd/dlv -``` -注意 : 修改"dlv-cert"證書, 選擇"顯示簡介"->"信任"->"程式碼簽名" 修改為: 始終信任 - -開啟首選項-工作區設定,配置 launch.json: - -```Go -{ - "version": "0.2.0", - "configurations": [ - { - "name": "main.go", - "type": "go", - "request": "launch", - "mode": "debug", - "remotePath": "", - "port": 2345, - "host": "127.0.0.1", - "program": "${workspaceRoot}",//工作空間路徑 - "env": {}, - "args": [], - "showLog": true - } - ] -} -``` - -## Atom - -Atom 是 Github 基於 Electron 和 web 技術建構的開源編輯器, 是一款很漂亮強大的編輯器缺點是速度比較慢。 - -首先要先安裝下 Atom,下載地址: https://atom.io/ - -然後安裝 go-plus 外掛: - - go-plus 是 Atom 上面的一款開源的 go 語言開發環境的的外掛 - - 它需要依賴下面的 go 語言工具: - -```Go -1.autocomplete-go :gocode 的程式碼自動提示 -2.gofmt :使用 goftm,goimports,goturns -3.builder-go:go-install 和 go-test,驗證程式碼,給出建議 -4.gometalinet-linter:goline,vet,gotype 的檢查 -5.navigator-godef:godef -6.tester-goo :go test -7.gorename :rename -``` - -在 Atom 中的 Preference 中可以找到 install 選單,輸入 go-plus,然後點選安裝(install) - -就會開始安裝 go-plus , go-plus 外掛會自動安裝對應的依賴外掛,如果沒有安裝對應的 go 的類別函式庫會自動執行: go get 安裝。 - - -## GoLand - -GoLand 是 JetBrains 公司推出的 Go 語言整合開發環境,是 Idea Go 外掛的強化版。GoLand 同樣基於 IntelliJ 平臺開發,支援 JetBrains 的外掛體系。 - -下載地址: https://www.jetbrains.com/go/ - -## Vim -Vim 是從 vi 發展出來的一個文字編輯器, 程式碼自動完成、編譯及錯誤跳轉等方便程式設計的功能特別豐富,在程式設計師中被廣泛使用。 - -vim-go 是 vim 上面的一款開源的 go 語言使用最為廣泛開發環境的的外掛 - -外掛地址:[github.com/fatih/vim-go](https://github.com/fatih/vim-go) - -vim 的外掛管理主要有[Pathogen](https://github.com/tpope/vim-pathogen)與[Vundle](https://github.com/VundleVim/Vundle.vim) -,但是其作用的方面不同。 -pathogen 是為了解決每一個外掛安裝後文件分散到多個目錄不好管理而存在的。vundle 是為了解決自動搜尋及下載外掛而存在的。 -這兩個外掛可同時使用。 - -1.安裝 Vundle - - -```sh -mkdir ~/.vim/bundle -git clone https://github.com/gmarik/Vundle.vim.git ~/.vim/bundle/Vundle.vim -``` - -修改.vimrc,將 Vundle 的相關配置置在最開始處([詳細參考 Vundle 的介紹文件](https://github.com/VundleVim/Vundle.vim)) - -```sh -set nocompatible " be iMproved, required -filetype off " required - -" set the runtime path to include Vundle and initialize -set rtp+=~/.vim/bundle/Vundle.vim -call vundle#begin() - -" let Vundle manage Vundle, required -Plugin 'gmarik/Vundle.vim' - -" All of your Plugins must be added before the following line -call vundle#end() " required -filetype plugin indent on " required -``` - -2.安裝 Vim-go - -修改~/.vimrc,在 vundle#begin 和 vundle#end 間增加一行: - -```sh - -Plugin 'fatih/vim-go' -``` - -在 Vim 內執行: PluginInstall - -3.安裝 YCM(Your Complete Me)進行自動自動完成 -在~/.vimrc 中新增一行: - -```sh - -Plugin 'Valloric/YouCompleteMe' -``` -在 Vim 內執行: PluginInstall - - -![](images/1.4.vim.png) - -圖 1.9 VIM 編輯器自動化提示 Go 介面 - -接著我們繼續配置 vim: - - 1. 配置 vim 高亮顯示 - - cp -r $GOROOT/misc/vim/* ~/.vim/ - - 2. 在~/.vimrc 檔案中增加語法高亮顯示 - - filetype plugin indent on - syntax on - - 3. 安裝[Gocode](https://github.com/nsf/gocode/) - - go get -u github.com/nsf/gocode - - gocode 預設安裝到`$GOPATH/bin`下面。 - - 4. 配置[Gocode](https://github.com/nsf/gocode/) - - ~ cd $GOPATH/src/github.com/nsf/gocode/vim - ~ ./update.bash - ~ gocode set propose-builtins true - propose-builtins true - ~ gocode set lib-path "/home/border/gocode/pkg/linux_amd64" - lib-path "/home/border/gocode/pkg/linux_amd64" - ~ gocode set - propose-builtins true - lib-path "/home/border/gocode/pkg/linux_amd64" - - >gocode set 裡面的兩個參數的含意說明: - > - >propose-builtins:是否自動提示 Go 的內建函式、型別和常數,預設為 false,不提示。 - > - >lib-path:預設情況下,gocode 只會搜尋**$GOPATH/pkg/$GOOS_$GOARCH** 和 **$GOROOT/pkg/$GOOS_$GOARCH**目錄下的套件,當然這個設定就是可以設定我們額外的 lib 能訪問的路徑 - - - 5. 恭喜你,安裝完成,你現在可以使用`:e main.go`體驗一下開發 Go 的樂趣。 - -更多 VIM 設定, 可參考 [ 連結](http://www.cnblogs.com/witcxc/archive/2011/12/28/2304704.html) - -## Emacs -Emacs 傳說中的神器,她不僅僅是一個編輯器,它是一個整合環境,或可稱它為整合開發環境,這些功能如讓使用者置身於全功能的作業系統中。 - - ![](images/1.4.emacs.png) - -圖 1.10 Emacs 編輯 Go 主介面 - -1. 配置 Emacs 高亮顯示 - - cp $GOROOT/misc/emacs/* ~/.emacs.d/ - -2. 安裝[Gocode](https://github.com/nsf/gocode/) - - go get -u github.com/nsf/gocode - - gocode 預設安裝到`$GOBIN`裡面下面。 - -3. 配置[Gocode](https://github.com/nsf/gocode/) - - - ~ cd $GOPATH/src/github.com/nsf/gocode/emacs - ~ cp go-autocomplete.el ~/.emacs.d/ - ~ gocode set propose-builtins true - propose-builtins true - ~ gocode set lib-path "/home/border/gocode/pkg/linux_amd64" // 換為你自己的路徑 - lib-path "/home/border/gocode/pkg/linux_amd64" - ~ gocode set - propose-builtins true - lib-path "/home/border/gocode/pkg/linux_amd64" - -4. 需要安裝 [Auto Completion](http://www.emacswiki.org/emacs/AutoComplete) - - 下載 AutoComplete 並解壓 - - ~ make install DIR=$HOME/.emacs.d/auto-complete - - 配置~/.emacs 檔案 - - ;;auto-complete - (require 'auto-complete-config) - (add-to-list 'ac-dictionary-directories "~/.emacs.d/auto-complete/ac-dict") - (ac-config-default) - (local-set-key (kbd "M-/") 'semantic-complete-analyze-inline) - (local-set-key "." 'semantic-complete-self-insert) - (local-set-key ">" 'semantic-complete-self-insert) - - 詳細資訊參考: http://www.emacswiki.org/emacs/AutoComplete - -5. 配置.emacs - - ;; golang mode - (require 'go-mode-load) - (require 'go-autocomplete) - ;; speedbar - ;; (speedbar 1) - (speedbar-add-supported-extension ".go") - (add-hook - 'go-mode-hook - '(lambda () - ;; gocode - (auto-complete-mode 1) - (setq ac-sources '(ac-source-go)) - ;; Imenu & Speedbar - (setq imenu-generic-expression - '(("type" "^type *\\([^ \t\n\r\f]*\\)" 1) - ("func" "^func *\\(.*\\) {" 1))) - (imenu-add-to-menubar "Index") - ;; Outline mode - (make-local-variable 'outline-regexp) - (setq outline-regexp "//\\.\\|//[^\r\n\f][^\r\n\f]\\|pack\\|func\\|impo\\|cons\\|var.\\|type\\|\t\t*....") - (outline-minor-mode 1) - (local-set-key "\M-a" 'outline-previous-visible-heading) - (local-set-key "\M-e" 'outline-next-visible-heading) - ;; Menu bar - (require 'easymenu) - (defconst go-hooked-menu - '("Go tools" - ["Go run buffer" go t] - ["Go reformat buffer" go-fmt-buffer t] - ["Go check buffer" go-fix-buffer t])) - (easy-menu-define - go-added-menu - (current-local-map) - "Go tools" - go-hooked-menu) - - ;; Other - (setq show-trailing-whitespace t) - )) - ;; helper function - (defun go () - "run current buffer" - (interactive) - (compile (concat "go run " (buffer-file-name)))) - - ;; helper function - (defun go-fmt-buffer () - "run gofmt on current buffer" - (interactive) - (if buffer-read-only - (progn - (ding) - (message "Buffer is read only")) - (let ((p (line-number-at-pos)) - (filename (buffer-file-name)) - (old-max-mini-window-height max-mini-window-height)) - (show-all) - (if (get-buffer "*Go Reformat Errors*") - (progn - (delete-windows-on "*Go Reformat Errors*") - (kill-buffer "*Go Reformat Errors*"))) - (setq max-mini-window-height 1) - (if (= 0 (shell-command-on-region (point-min) (point-max) "gofmt" "*Go Reformat Output*" nil "*Go Reformat Errors*" t)) - (progn - (erase-buffer) - (insert-buffer-substring "*Go Reformat Output*") - (goto-char (point-min)) - (forward-line (1- p))) - (with-current-buffer "*Go Reformat Errors*" - (progn - (goto-char (point-min)) - (while (re-search-forward "" nil t) - (replace-match filename)) - (goto-char (point-min)) - (compilation-mode)))) - (setq max-mini-window-height old-max-mini-window-height) - (delete-windows-on "*Go Reformat Output*") - (kill-buffer "*Go Reformat Output*")))) - ;; helper function - (defun go-fix-buffer () - "run gofix on current buffer" - (interactive) - (show-all) - (shell-command-on-region (point-min) (point-max) "go tool fix -diff")) - -6. 恭喜你,你現在可以體驗在神器中開發 Go 的樂趣。預設 speedbar 是關閉的,如果開啟需要把 ;; (speedbar 1) 前面的註釋去掉,或者也可以透過 *M-x speedbar* 手動開啟。 - -## Eclipse -Eclipse 也是非常常用的開發利器,以下介紹如何使用 Eclipse 來編寫 Go 程式。 - - ![](images/1.4.eclipse1.png) - -圖 1.11 Eclipse 編輯 Go 的主介面 - -1. 首先下載並安裝好[Eclipse](http://www.eclipse.org/) - -2. 下載[goclipse](https://code.google.com/p/goclipse/)外掛 - - http://code.google.com/p/goclipse/wiki/InstallationInstructions - -3. 下載 gocode,用於 go 的程式碼自動完成提示 - - gocode 的 github 地址: - - https://github.com/nsf/gocode - - 在 windows 下要安裝 git,通常用[msysgit](https://code.google.com/p/msysgit/) - - 再在 cmd 下安裝: - - go get -u github.com/nsf/gocode - - 也可以下載程式碼,直接用 go build 來編譯,會產生 gocode.exe - -4. 下載[MinGW](http://sourceforge.net/projects/mingw/files/MinGW/)並按要求裝好 - -5. 配置外掛 - - Windows->Reference->Go - - (1).配置 Go 的編譯器 - - ![](images/1.4.eclipse2.png) - - 圖 1.12 設定 Go 的一些基礎資訊 - - - (2).配置 Gocode(可選,程式碼自動完成),設定 Gocode 路徑為之前產生的 gocode.exe 檔案 - - ![](images/1.4.eclipse3.png) - - 圖 1.13 設定 gocode 資訊 - - (3).配置 GDB(可選,做除錯用),設定 GDB 路徑為 MingW 安裝目錄下的 gdb.exe 檔案 - - ![](images/1.4.eclipse4.png) - - 圖 1.14 設定 GDB 資訊 - -6. 測試是否成功 - - 建立一個 go 工程,再建立一個 hello.go。如下圖: - - ![](images/1.4.eclipse5.png) - - 圖 1.15 建立專案編輯檔案 - - 除錯如下(要在 console 中用輸入命令來除錯): - - ![](images/1.4.eclipse6.png) - - 圖 1.16 除錯 Go 程式 - -## IntelliJ IDEA -熟悉 Java 的讀者應該對於 idea 不陌生,idea 是透過一個外掛來支援 go 語言的高亮語法,程式碼提示和重構實現。 - -1. 先下載 idea,idea 支援多平臺:win,mac,linux,如果有錢就買個正式版,如果不行就使用社群免費版,對於只是開發 Go 語言來說免費版足夠用了 - - ![](images/1.4.idea1.png) - -2. 安裝 Go 外掛,點選選單 File 中的 Setting,找到 Plugins,點選,Broswer repo 按鈕。國內的使用者可能會報錯,自己解決哈。 - - ![](images/1.4.idea3.png) - -3. 這時候會看見很多外掛,搜尋找到 Golang,雙擊,download and install。等到 golang 那一行後面出現 Downloaded 標誌後,點 OK。 - - ![](images/1.4.idea4.png) - - 然後點 Apply .這時候 IDE 會要求你重啟。 - -4. 重啟完畢後,建立新專案會發現已經可以建立 golang 專案了: - - ![](images/1.4.idea5.png) - - 下一步,會要求你輸入 go sdk 的位置,一般都安裝在 C:\Go,linux 和 mac 根據自己的安裝目錄設定,選中目錄確定,就可以了。 - -## links - * [目錄]() - * 上一節: [Go 命令](<01.3.md>) - * 下一節: [總結](<01.5.md>) +# 1.4 Go 開發工具 + +本節我將介紹幾個開發工具,它們都具有自動化提示,自動化 fmt 功能。因為它們都是跨平臺的,所以安裝步驟之類別的都是通用的。 + +## LiteIDE + + LiteIDE 是一款專門為 Go 語言開發的跨平臺輕量級整合開發環境(IDE),由 visualfc 編寫。 + + ![](images/1.4.liteide.png) + +圖 1.4 LiteIDE 主介面 + +**LiteIDE 主要特點:** + +* 支援主流作業系統 + * Windows + * Linux + * MacOS X +* Go 編譯環境管理和切換 + * 管理和切換多個 Go 編譯環境 + * 支援 Go 語言交叉編譯 +* 與 Go 標準一致的專案管理方式 + * 基於 GOPATH 的套件瀏覽器 + * 基於 GOPATH 的編譯系統 + * 基於 GOPATH 的 Api 文件檢索 +* Go 語言的編輯支援 + * 類別瀏覽器和大綱顯示 + * Gocode(程式碼自動完成工具)的完美支援 + * Go 語言文件檢視和 Api 快速檢索 + * 程式碼表達式資訊顯示`F1` + * 原始碼定義跳轉支援`F2` + * Gdb 斷點和除錯支援 + * gofmt 自動格式化支援 +* 其他特徵 + * 支援多國語言介面顯示 + * 完全外掛體系結構 + * 支援編輯器配色方案 + * 基於 Kate 的語法顯示支援 + * 基於全文的單詞自動完成 + * 支援鍵盤快捷鍵繫結方案 + * Markdown 文件編輯支援 + * 即時預覽和同步顯示 + * 自訂 CSS 顯示 + * 可匯出 HTML 和 PDF 文件 + * 批量轉換/合併為 HTML/PDF 文件 + +**LiteIDE 安裝配置** + +* LiteIDE 安裝 + * 下載地址 + * 原始碼地址 + + 首先安裝好 Go 語言環境,然後根據作業系統下載 LiteIDE 對應的壓縮檔案直接解壓即可使用。 + +* 編譯環境設定 + + 根據自身系統要求切換和配置 LiteIDE 當前使用的環境變數。 + + 以 Windows 作業系統,64 位 Go 語言為例, + 工具欄的環境配置中選擇 win64,點 ` 編輯環境`,進入 LiteIDE 編輯 win64.env 檔案 + + GOROOT=c:\go + GOBIN= + GOARCH=amd64 + GOOS=windows + CGO_ENABLED=1 + + PATH=%GOBIN%;%GOROOT%\bin;%PATH% + 。。。 + + 將其中的 `GOROOT=c:\go` 修改為當前 Go 安裝路徑,存檔即可,如果有 MinGW64,可以將 `c:\MinGW64\bin` 加入 PATH 中以便 go 呼叫 gcc 支援 CGO 編譯。 + + 以 Linux 作業系統,64 位 Go 語言為例, + 工具欄的環境配置中選擇 linux64,點 ` 編輯環境`,進入 LiteIDE 編輯 linux64.env 檔案 + + GOROOT=$HOME/go + GOBIN= + GOARCH=amd64 + GOOS=linux + CGO_ENABLED=1 + + PATH=$GOBIN:$GOROOT/bin:$PATH + 。。。 + + 將其中的`GOROOT=$HOME/go`修改為當前 Go 安裝路徑,存檔即可。 + +* GOPATH 設定 + + Go 語言的工具鏈使用 GOPATH 設定,是 Go 語言開發的專案路徑列表,在命令列中輸入(在 LiteIDE 中也可以`Ctrl+,`直接輸入)`go help gopath`快速檢視 GOPATH 文件。 + + 在 LiteIDE 中可以方便的檢視和設定 GOPATH。透過 ` 選單-檢視-GOPATH`設定,可以檢視系統中已存在的 GOPATH 列表, + 同時可根據需要新增專案目錄到自訂 GOPATH 列表中。 + +## Sublime Text + + 這裡將介紹 Sublime Text 3(以下簡稱 Sublime)+ GoSublime + gocode 的組合,那麼為什麼選擇這個組合呢? + + - 自動化提示程式碼,如下圖所示 + + ![](images/1.4.sublime1.png) + + 圖 1.5 sublime 自動化提示介面 + + - 儲存的時候自動格式化程式碼,讓您編寫的程式碼更加美觀,符合 Go 的標準。 + - 支援專案管理 + + ![](images/1.4.sublime2.png) + + 圖 1.6 sublime 專案管理介面 + + - 支援語法高亮 + - Sublime Text 3 可免費使用,只是儲存次數達到一定數量之後就會提示是否購買,點選取消繼續用,和正式註冊版本沒有任何區別。 + + +接下來就開始講如何安裝,下載 [Sublime](http://www.sublimetext.com/) + + 根據自己相應的系統下載相應的版本,然後開啟 Sublime,對於不熟悉 Sublime 的同學可以先看一下這篇文章[Sublime Text 全程指南](http://blog.jobbole.com/88648/)或者[sublime text3 入門課程](http://blog.csdn.net/sam976/article/details/52076271) + + 1. 開啟之後安裝 Package Control:Ctrl+` 開啟命令列,執行如下程式碼: + + 適用於 Sublime Text 3: + +```Go +import urllib.request,os;pf='Package Control.sublime-package';ipp=sublime.installed_packages_path();urllib.request.install_opener(urllib.request.build_opener(urllib.request.ProxyHandler()));open(os.path.join(ipp,pf),'wb').write(urllib.request.urlopen('http://sublime.wbond.net/'+pf.replace(' ','%20')).read()) +``` + 適用於 Sublime Text 2: + +```Go +import urllib2,os;pf='Package Control.sublime-package';ipp=sublime.installed_packages_path();os.makedirs(ipp)ifnotos.path.exists(ipp)elseNone;urllib2.install_opener(urllib2.build_opener(urllib2.ProxyHandler()));open(os.path.join(ipp,pf),'wb').write(urllib2.urlopen('http://sublime.wbond.net/'+pf.replace(' ','%20')).read());print('Please restart Sublime Text to finish installation') +``` + + 這個時候重啟一下 Sublime,可以發現在在選單欄多了一個如下的節目,說明 Package Control 已經安裝成功了。 + + ![](images/1.4.sublime3.png) + + 圖 1.7 sublime 套件管理 + + + 2. 安裝完之後就可以安裝 Sublime 的外掛了。需安裝 GoSublime、SidebarEnhancements 和 Go Build,安裝外掛之後記得重啟 Sublime 生效,Ctrl+Shift+p 開啟 Package Controll 輸入`pcip`(即“Package Control: Install Package”的縮寫)。 + + 這個時候看左下角顯示正在讀取套件資料,完成之後出現如下介面 + + ![](images/1.4.sublime4.png) + + 圖 1.8 sublime 安裝外掛介面 + + 這個時候輸入 GoSublime,按確定就開始安裝了。同理應用於 SidebarEnhancements 和 Go Build。 + + 3. 安裝 [gocode](https://github.com/nsf/gocode/) + + go get -u github.com/nsf/gocode + + gocode 將會安裝在預設`$GOBIN` + + 另外建議安裝 gotests(產生測試程式碼): + + + 先在 sublime 安裝 gotests 外掛,再執行: + + +```Go +go get -u -v github.com/cweill/gotests/... +``` + + 3. 驗證是否安裝成功,你可以開啟 Sublime,開啟 main.go,看看語法是不是高亮了,輸入 `import` 是不是自動化提示了,`import "fmt"`之後,輸入`fmt.`是不是自動化提示有函數了。 + + 如果已經出現這個提示,那說明你已經安裝完成了,並且完成了自動提示。 + + 如果沒有出現這樣的提示,一般就是你的`$PATH`沒有配置正確。你可以開啟終端,輸入 gocode,是不是能夠正確執行,如果不行就說明`$PATH`沒有配置正確。 + (針對 XP)有時候在終端能執行成功,但 sublime 無提示或者編譯解碼錯誤,請安裝 sublime text3 和 convert utf8 外掛試一試 + + 4. MacOS 下已經設定了$GOROOT, $GOPATH, $GOBIN,還是沒有自動提示怎麼辦。 + + 請在 sublime 中使用 command + 9, 然後輸入 env 檢查$PATH, GOROOT, $GOPATH, $GOBIN 等變數, 如果沒有請採用下面的方法。 + + 首先建立下面的連線, 然後從 Terminal 中直接啟動 sublime + + + ln -s /Applications/Sublime\ Text\ 2.app/Contents/SharedSupport/bin/subl /usr/local/bin/sublime + + +## Visual Studio Code + +VSCode 是微軟基於 Electron 和 web 技術建構的開源編輯器, 是一款很強大的編輯器。開源地址:https://github.com/Microsoft/VSCode + +1、安裝 Visual Studio Code 最新版 + +官方網站:https://code.visualstudio.com/ +下載 Visual Studio Code 最新版,安裝過程略。 + +2、安裝 Go 外掛 + +點選右邊的 Extensions 圖示 +搜尋 Go 外掛 +在外掛列表中,選擇 Go,進行安裝,安裝之後,系統會提示重啟 Visual Studio Code。 + +建議把自動儲存功能開啟。開啟方法為:選擇選單 File,點選 Auto save。 + +VSCode 程式碼設定可用於 Go 擴充套件。這些都可以在使用者的喜好來設定或工作區設定(.VSCode/settings.json)。 + +開啟首選項-使用者設定 settings.json: + +```Go + +{ + "go.buildOnSave": true, + "go.lintOnSave": true, + "go.vetOnSave": true, + "go.buildFlags": [], + "go.lintFlags": [], + "go.vetFlags": [], + "go.coverOnSave": false, + "go.useCodeSnippetsOnFunctionSuggest": false, + "go.formatOnSave": true, + //goimports + "go.formatTool": "goreturns", + "go.goroot": "",//你的 Goroot + + "go.gopath": "",//你的 Gopath + +} +``` + +接著安裝相依套件支援(網路不穩定,請直接到 GitHub [Golang](https://github.com/golang) 下載再移動到相關目錄): + +```Go +go get -u -v github.com/nsf/gocode +go get -u -v github.com/rogpeppe/godef +go get -u -v github.com/zmb3/gogetdoc +go get -u -v github.com/golang/lint/golint +go get -u -v github.com/lukehoban/go-outline +go get -u -v sourcegraph.com/sqs/goreturns +go get -u -v golang.org/x/tools/cmd/gorename +go get -u -v github.com/tpng/gopkgs +go get -u -v github.com/newhook/go-symbols +go get -u -v golang.org/x/tools/cmd/guru +go get -u -v github.com/cweill/gotests/... +``` + +VSCode 還有一項很強大的功能就是斷點除錯,結合 [delve](https://github.com/derekparker/delve) 可以很好的進行 Go 程式碼除錯 + +```Go + +go get -v -u github.com/peterh/liner github.com/derekparker/delve/cmd/dlv + +brew install go-delve/delve/delve(mac 可選) +``` + +如果有問題再來一遍: + +```Go +go get -v -u github.com/peterh/liner github.com/derekparker/delve/cmd/dlv +``` +注意 : 修改"dlv-cert"證書, 選擇"顯示簡介"->"信任"->"程式碼簽名" 修改為: 始終信任 + +開啟首選項-工作區設定,配置 launch.json: + +```Go +{ + "version": "0.2.0", + "configurations": [ + { + "name": "main.go", + "type": "go", + "request": "launch", + "mode": "debug", + "remotePath": "", + "port": 2345, + "host": "127.0.0.1", + "program": "${workspaceRoot}",//工作空間路徑 + "env": {}, + "args": [], + "showLog": true + } + ] +} +``` + +## Atom + +Atom 是 GitHub 基於 Electron 和 web 技術建構的開源編輯器, 是一款很漂亮強大的編輯器缺點是速度比較慢。 + +首先要先安裝下 Atom,下載地址: https://atom.io/ + +然後安裝 go-plus 外掛: + + go-plus 是 Atom 上面的一款開源的 go 語言開發環境的的外掛 + + 它需要依賴下面的 go 語言工具: + +```Go +1.autocomplete-go :gocode 的程式碼自動提示 +2.gofmt :使用 goftm,goimports,goturns +3.builder-go:go-install 和 go-test,驗證程式碼,給出建議 +4.gometalinet-linter:goline,vet,gotype 的檢查 +5.navigator-godef:godef +6.tester-goo :go test +7.gorename :rename +``` + +在 Atom 中的 Preference 中可以找到 install 選單,輸入 go-plus,然後點選安裝(install) + +就會開始安裝 go-plus , go-plus 外掛會自動安裝對應的依賴外掛,如果沒有安裝對應的 go 的類別函式庫會自動執行: go get 安裝。 + + +## GoLand + +GoLand 是 JetBrains 公司推出的 Go 語言整合開發環境,是 Idea Go 外掛的強化版。GoLand 同樣基於 IntelliJ 平臺開發,支援 JetBrains 的外掛體系。 + +下載地址: https://www.jetbrains.com/go/ + +## Vim +Vim 是從 vi 發展出來的一個文字編輯器, 程式碼自動完成、編譯及錯誤跳轉等方便程式設計的功能特別豐富,在程式設計師中被廣泛使用。 + +vim-go 是 vim 上面的一款開源的 go 語言使用最為廣泛開發環境的的外掛 + +外掛地址:[github.com/fatih/vim-go](https://github.com/fatih/vim-go) + +vim 的外掛管理主要有[Pathogen](https://github.com/tpope/vim-pathogen)與[Vundle](https://github.com/VundleVim/Vundle.vim) +,但是其作用的方面不同。 +pathogen 是為了解決每一個外掛安裝後文件分散到多個目錄不好管理而存在的。vundle 是為了解決自動搜尋及下載外掛而存在的。 +這兩個外掛可同時使用。 + +1.安裝 Vundle + + +```sh +mkdir ~/.vim/bundle +git clone https://github.com/gmarik/Vundle.vim.git ~/.vim/bundle/Vundle.vim +``` + +修改.vimrc,將 Vundle 的相關配置置在最開始處([詳細參考 Vundle 的介紹文件](https://github.com/VundleVim/Vundle.vim)) + +```sh +set nocompatible " be iMproved, required +filetype off " required + +" set the runtime path to include Vundle and initialize +set rtp+=~/.vim/bundle/Vundle.vim +call vundle#begin() + +" let Vundle manage Vundle, required +Plugin 'gmarik/Vundle.vim' + +" All of your Plugins must be added before the following line +call vundle#end() " required +filetype plugin indent on " required +``` + +2.安裝 Vim-go + +修改~/.vimrc,在 vundle#begin 和 vundle#end 間增加一行: + +```sh + +Plugin 'fatih/vim-go' +``` + +在 Vim 內執行: PluginInstall + +3.安裝 YCM(Your Complete Me)進行自動自動完成 +在~/.vimrc 中新增一行: + +```sh + +Plugin 'Valloric/YouCompleteMe' +``` +在 Vim 內執行: PluginInstall + + +![](images/1.4.vim.png) + +圖 1.9 VIM 編輯器自動化提示 Go 介面 + +接著我們繼續配置 vim: + + 1. 配置 vim 高亮顯示 + + cp -r $GOROOT/misc/vim/* ~/.vim/ + + 2. 在~/.vimrc 檔案中增加語法高亮顯示 + + filetype plugin indent on + syntax on + + 3. 安裝[Gocode](https://github.com/nsf/gocode/) + + go get -u github.com/nsf/gocode + + gocode 預設安裝到`$GOPATH/bin`下面。 + + 4. 配置[Gocode](https://github.com/nsf/gocode/) + + ~ cd $GOPATH/src/github.com/nsf/gocode/vim + ~ ./update.bash + ~ gocode set propose-builtins true + propose-builtins true + ~ gocode set lib-path "/home/border/gocode/pkg/linux_amd64" + lib-path "/home/border/gocode/pkg/linux_amd64" + ~ gocode set + propose-builtins true + lib-path "/home/border/gocode/pkg/linux_amd64" + + >gocode set 裡面的兩個參數的含意說明: + > + >propose-builtins:是否自動提示 Go 的內建函式、型別和常數,預設為 false,不提示。 + > + >lib-path:預設情況下,gocode 只會搜尋**$GOPATH/pkg/$GOOS_$GOARCH** 和 **$GOROOT/pkg/$GOOS_$GOARCH**目錄下的套件,當然這個設定就是可以設定我們額外的 lib 能訪問的路徑 + + + 5. 恭喜你,安裝完成,你現在可以使用`:e main.go`體驗一下開發 Go 的樂趣。 + +更多 VIM 設定, 可參考 [ 連結](http://www.cnblogs.com/witcxc/archive/2011/12/28/2304704.html) + +## Emacs +Emacs 傳說中的神器,她不僅僅是一個編輯器,它是一個整合環境,或可稱它為整合開發環境,這些功能如讓使用者置身於全功能的作業系統中。 + + ![](images/1.4.emacs.png) + +圖 1.10 Emacs 編輯 Go 主介面 + +1. 配置 Emacs 高亮顯示 + + cp $GOROOT/misc/emacs/* ~/.emacs.d/ + +2. 安裝[Gocode](https://github.com/nsf/gocode/) + + go get -u github.com/nsf/gocode + + gocode 預設安裝到`$GOBIN`裡面下面。 + +3. 配置[Gocode](https://github.com/nsf/gocode/) + + + ~ cd $GOPATH/src/github.com/nsf/gocode/emacs + ~ cp go-autocomplete.el ~/.emacs.d/ + ~ gocode set propose-builtins true + propose-builtins true + ~ gocode set lib-path "/home/border/gocode/pkg/linux_amd64" // 換為你自己的路徑 + lib-path "/home/border/gocode/pkg/linux_amd64" + ~ gocode set + propose-builtins true + lib-path "/home/border/gocode/pkg/linux_amd64" + +4. 需要安裝 [Auto Completion](http://www.emacswiki.org/emacs/AutoComplete) + + 下載 AutoComplete 並解壓 + + ~ make install DIR=$HOME/.emacs.d/auto-complete + + 配置~/.emacs 檔案 + + ;;auto-complete + (require 'auto-complete-config) + (add-to-list 'ac-dictionary-directories "~/.emacs.d/auto-complete/ac-dict") + (ac-config-default) + (local-set-key (kbd "M-/") 'semantic-complete-analyze-inline) + (local-set-key "." 'semantic-complete-self-insert) + (local-set-key ">" 'semantic-complete-self-insert) + + 詳細資訊參考: http://www.emacswiki.org/emacs/AutoComplete + +5. 配置.emacs + + ;; golang mode + (require 'go-mode-load) + (require 'go-autocomplete) + ;; speedbar + ;; (speedbar 1) + (speedbar-add-supported-extension ".go") + (add-hook + 'go-mode-hook + '(lambda () + ;; gocode + (auto-complete-mode 1) + (setq ac-sources '(ac-source-go)) + ;; Imenu & Speedbar + (setq imenu-generic-expression + '(("type" "^type *\\([^ \t\n\r\f]*\\)" 1) + ("func" "^func *\\(.*\\) {" 1))) + (imenu-add-to-menubar "Index") + ;; Outline mode + (make-local-variable 'outline-regexp) + (setq outline-regexp "//\\.\\|//[^\r\n\f][^\r\n\f]\\|pack\\|func\\|impo\\|cons\\|var.\\|type\\|\t\t*....") + (outline-minor-mode 1) + (local-set-key "\M-a" 'outline-previous-visible-heading) + (local-set-key "\M-e" 'outline-next-visible-heading) + ;; Menu bar + (require 'easymenu) + (defconst go-hooked-menu + '("Go tools" + ["Go run buffer" go t] + ["Go reformat buffer" go-fmt-buffer t] + ["Go check buffer" go-fix-buffer t])) + (easy-menu-define + go-added-menu + (current-local-map) + "Go tools" + go-hooked-menu) + + ;; Other + (setq show-trailing-whitespace t) + )) + ;; helper function + (defun go () + "run current buffer" + (interactive) + (compile (concat "go run " (buffer-file-name)))) + + ;; helper function + (defun go-fmt-buffer () + "run gofmt on current buffer" + (interactive) + (if buffer-read-only + (progn + (ding) + (message "Buffer is read only")) + (let ((p (line-number-at-pos)) + (filename (buffer-file-name)) + (old-max-mini-window-height max-mini-window-height)) + (show-all) + (if (get-buffer "*Go Reformat Errors*") + (progn + (delete-windows-on "*Go Reformat Errors*") + (kill-buffer "*Go Reformat Errors*"))) + (setq max-mini-window-height 1) + (if (= 0 (shell-command-on-region (point-min) (point-max) "gofmt" "*Go Reformat Output*" nil "*Go Reformat Errors*" t)) + (progn + (erase-buffer) + (insert-buffer-substring "*Go Reformat Output*") + (goto-char (point-min)) + (forward-line (1- p))) + (with-current-buffer "*Go Reformat Errors*" + (progn + (goto-char (point-min)) + (while (re-search-forward "" nil t) + (replace-match filename)) + (goto-char (point-min)) + (compilation-mode)))) + (setq max-mini-window-height old-max-mini-window-height) + (delete-windows-on "*Go Reformat Output*") + (kill-buffer "*Go Reformat Output*")))) + ;; helper function + (defun go-fix-buffer () + "run gofix on current buffer" + (interactive) + (show-all) + (shell-command-on-region (point-min) (point-max) "go tool fix -diff")) + +6. 恭喜你,你現在可以體驗在神器中開發 Go 的樂趣。預設 speedbar 是關閉的,如果開啟需要把 ;; (speedbar 1) 前面的註釋去掉,或者也可以透過 *M-x speedbar* 手動開啟。 + +## Eclipse +Eclipse 也是非常常用的開發利器,以下介紹如何使用 Eclipse 來編寫 Go 程式。 + + ![](images/1.4.eclipse1.png) + +圖 1.11 Eclipse 編輯 Go 的主介面 + +1. 首先下載並安裝好[Eclipse](http://www.eclipse.org/) + +2. 下載[goclipse](https://code.google.com/p/goclipse/)外掛 + + http://code.google.com/p/goclipse/wiki/InstallationInstructions + +3. 下載 gocode,用於 go 的程式碼自動完成提示 + + gocode 的 GitHub 地址: + + https://github.com/nsf/gocode + + 在 windows 下要安裝 git,通常用[msysgit](https://code.google.com/p/msysgit/) + + 再在 cmd 下安裝: + + go get -u github.com/nsf/gocode + + 也可以下載程式碼,直接用 go build 來編譯,會產生 gocode.exe + +4. 下載[MinGW](http://sourceforge.net/projects/mingw/files/MinGW/)並按要求裝好 + +5. 配置外掛 + + Windows->Reference->Go + + (1).配置 Go 的編譯器 + + ![](images/1.4.eclipse2.png) + + 圖 1.12 設定 Go 的一些基礎資訊 + + + (2).配置 Gocode(可選,程式碼自動完成),設定 Gocode 路徑為之前產生的 gocode.exe 檔案 + + ![](images/1.4.eclipse3.png) + + 圖 1.13 設定 gocode 資訊 + + (3).配置 GDB(可選,做除錯用),設定 GDB 路徑為 MingW 安裝目錄下的 gdb.exe 檔案 + + ![](images/1.4.eclipse4.png) + + 圖 1.14 設定 GDB 資訊 + +6. 測試是否成功 + + 建立一個 go 工程,再建立一個 hello.go。如下圖: + + ![](images/1.4.eclipse5.png) + + 圖 1.15 建立專案編輯檔案 + + 除錯如下(要在 console 中用輸入命令來除錯): + + ![](images/1.4.eclipse6.png) + + 圖 1.16 除錯 Go 程式 + +## IntelliJ IDEA +熟悉 Java 的讀者應該對於 idea 不陌生,idea 是透過一個外掛來支援 go 語言的高亮語法,程式碼提示和重構實現。 + +1. 先下載 idea,idea 支援多平臺:win,mac,linux,如果有錢就買個正式版,如果不行就使用社群免費版,對於只是開發 Go 語言來說免費版足夠用了 + + ![](images/1.4.idea1.png) + +2. 安裝 Go 外掛,點選選單 File 中的 Setting,找到 Plugins,點選,Broswer repo 按鈕。國內的使用者可能會報錯,自己解決哈。 + + ![](images/1.4.idea3.png) + +3. 這時候會看見很多外掛,搜尋找到 Golang,雙擊,download and install。等到 golang 那一行後面出現 Downloaded 標誌後,點 OK。 + + ![](images/1.4.idea4.png) + + 然後點 Apply .這時候 IDE 會要求你重啟。 + +4. 重啟完畢後,建立新專案會發現已經可以建立 golang 專案了: + + ![](images/1.4.idea5.png) + + 下一步,會要求你輸入 go sdk 的位置,一般都安裝在 C:\Go,linux 和 mac 根據自己的安裝目錄設定,選中目錄確定,就可以了。 + +## links + * [目錄]() + * 上一節: [Go 命令](<01.3.md>) + * 下一節: [總結](<01.5.md>) diff --git a/zh-tw/05.4.md b/zh-tw/05.4.md index 9366fa5c..0619d67e 100644 --- a/zh-tw/05.4.md +++ b/zh-tw/05.4.md @@ -13,7 +13,7 @@ Go 實現的支援 PostgreSQL 的驅動也很多,因為國外很多人在開 - https://github.com/jbarham/gopgsqldriver 支援 database/sql 驅動,純 Go 寫的 - https://github.com/lxn/go-pgsql 支援 database/sql 驅動,純 Go 寫的 -在下面的範例中我採用了第一個驅動,因為它目前使用的人最多,在 github 上也比較活躍。 +在下面的範例中我採用了第一個驅動,因為它目前使用的人最多,在 GitHub 上也比較活躍。 ## 範例程式碼 資料庫建表語句: diff --git a/zh-tw/13.6.md b/zh-tw/13.6.md index 9a6848b4..ab93a6b1 100644 --- a/zh-tw/13.6.md +++ b/zh-tw/13.6.md @@ -1,7 +1,7 @@ -# 13.6 小結 -這一章我們主要介紹了如何實現一個基礎的 Go 語言框架,框架包含有路由設計,由於 Go 內建的 http 套件中路由的一些不足點,我們設計了動態路由規則,然後介紹了 MVC 模式中的 Controller 設計,controller 實現了 REST 的實現,這個主要思路來源於 tornado 框架,然後設計實現了範本的 layout 以及自動化渲染等技術,主要採用了 Go 內建的範本引擎,最後我們介紹了一些輔助的日誌、配置等資訊的設計,透過這些設計我們實現了一個基礎的框架 beego,目前該框架已經開源在 github,最後我們透過 beego 實現了一個部落格系統,透過範例程式碼詳細的展現了如何快速的開發一個站點。 - -## links - * [目錄]() - * 上一章: [實現部落格的增刪改](<13.5.md>) - * 下一節: [擴充套件 Web 框架](<14.0.md>) \ No newline at end of file +# 13.6 小結 +這一章我們主要介紹了如何實現一個基礎的 Go 語言框架,框架包含有路由設計,由於 Go 內建的 http 套件中路由的一些不足點,我們設計了動態路由規則,然後介紹了 MVC 模式中的 Controller 設計,controller 實現了 REST 的實現,這個主要思路來源於 tornado 框架,然後設計實現了範本的 layout 以及自動化渲染等技術,主要採用了 Go 內建的範本引擎,最後我們介紹了一些輔助的日誌、配置等資訊的設計,透過這些設計我們實現了一個基礎的框架 beego,目前該框架已經開源在 GitHub,最後我們透過 beego 實現了一個部落格系統,透過範例程式碼詳細的展現了如何快速的開發一個站點。 + +## links + * [目錄]() + * 上一章: [實現部落格的增刪改](<13.5.md>) + * 下一節: [擴充套件 Web 框架](<14.0.md>) diff --git a/zh-tw/14.4.md b/zh-tw/14.4.md index 66bec5d9..83393c91 100644 --- a/zh-tw/14.4.md +++ b/zh-tw/14.4.md @@ -1,275 +1,275 @@ -# 14.4 使用者認證 -在開發 Web 應用過程中,使用者認證是開發者經常遇到的問題,使用者登入、註冊、登出等操作,而一般認證也分為三個方面的認證 - -- HTTP Basic 和 HTTP Digest 認證 -- 第三方整合認證:QQ、微博、豆瓣、OPENID、google、github、facebook 和 twitter 等 -- 自訂的使用者登入、註冊、登出,一般都是基於 session、cookie 認證 - -beego 目前沒有針對這三種方式進行任何形式的整合,但是可以充分的利用第三方開源函式庫來實現上面的三種方式的使用者認證,不過後續 beego 會對前面兩種認證逐步整合。 - -## HTTP Basic 和 HTTP Digest 認證 -這兩個認證是一些應用採用的比較簡單的認證,目前已經有開源的第三方函式庫支援這兩個認證: - -```Go - -github.com/abbot/go-http-auth -``` -下面程式碼示範了如何把這個函式庫引入 beego 中從而實現認證: - -```Go - -package controllers - -import ( - "github.com/abbot/go-http-auth" - "github.com/astaxie/beego" -) - -func Secret(user, realm string) string { - if user == "john" { - // password is "hello" - return "$1$dlPL2MqE$oQmn16q49SqdmhenQuNgs1" - } - return "" -} - -type MainController struct { - beego.Controller -} - -func (this *MainController) Prepare() { - a := auth.NewBasicAuthenticator("example.com", Secret) - if username := a.CheckAuth(this.Ctx.Request); username == "" { - a.RequireAuth(this.Ctx.ResponseWriter, this.Ctx.Request) - } -} - -func (this *MainController) Get() { - this.Data["Username"] = "astaxie" - this.Data["Email"] = "astaxie@gmail.com" - this.TplNames = "index.tpl" -} -``` -上面程式碼利用了 beego 的 prepare 函式,在執行正常邏輯之前呼叫了認證函式,這樣就非常簡單的實現了 http auth,digest 的認證也是同樣的原理。 - -## oauth 和 oauth2 的認證 -oauth 和 oauth2 是目前比較流行的兩種認證方式,還好第三方有一個函式庫實現了這個認證,但是是國外實現的,並沒有 QQ、微博之類別的國內應用認證整合: - -```Go - -github.com/bradrydzewski/go.auth -``` -下面程式碼示範了如何把該函式庫引入 beego 中從而實現 oauth 的認證,這裡以 github 為例示範: - -1. 新增兩條路由 - -```Go - -beego.RegisterController("/auth/login", &controllers.GithubController{}) -beego.RegisterController("/mainpage", &controllers.PageController{}) -``` -2. 然後我們處理 GithubController 登陸的頁面: - -```Go -package controllers - -import ( - "github.com/astaxie/beego" - "github.com/bradrydzewski/go.auth" -) - -const ( - githubClientKey = "a0864ea791ce7e7bd0df" - githubSecretKey = "a0ec09a647a688a64a28f6190b5a0d2705df56ca" -) - -type GithubController struct { - beego.Controller -} - -func (this *GithubController) Get() { - // set the auth parameters - auth.Config.CookieSecret = []byte("7H9xiimk2QdTdYI7rDddfJeV") - auth.Config.LoginSuccessRedirect = "/mainpage" - auth.Config.CookieSecure = false - - githubHandler := auth.Github(githubClientKey, githubSecretKey) - - githubHandler.ServeHTTP(this.Ctx.ResponseWriter, this.Ctx.Request) -} -``` - -3. 處理登陸成功之後的頁面 - -```Go -package controllers - -import ( - "github.com/astaxie/beego" - "github.com/bradrydzewski/go.auth" - "net/http" - "net/url" -) - -type PageController struct { - beego.Controller -} - -func (this *PageController) Get() { - // set the auth parameters - auth.Config.CookieSecret = []byte("7H9xiimk2QdTdYI7rDddfJeV") - auth.Config.LoginSuccessRedirect = "/mainpage" - auth.Config.CookieSecure = false - - user, err := auth.GetUserCookie(this.Ctx.Request) - - //if no active user session then authorize user - if err != nil || user.Id() == "" { - http.Redirect(this.Ctx.ResponseWriter, this.Ctx.Request, auth.Config.LoginRedirect, http.StatusSeeOther) - return - } - - //else, add the user to the URL and continue - this.Ctx.Request.URL.User = url.User(user.Id()) - this.Data["pic"] = user.Picture() - this.Data["id"] = user.Id() - this.Data["name"] = user.Name() - this.TplNames = "home.tpl" -} -``` - -整個的流程如下,首先開啟瀏覽器輸入地址: - -![](images/14.4.github.png) - -圖 14.4 顯示帶有登入按鈕的首頁 - -然後點選連結出現如下介面: - -![](images/14.4.github2.png) - -圖 14.5 點選登入按鈕後顯示 github 的授權頁 - -然後點選 Authorize app 就出現如下介面: - -![](images/14.4.github3.png) - -圖 14.6 授權登入之後顯示的取得到的 github 資訊頁 - -## 自訂認證 -自訂的認證一般都是和 session 結合驗證的,如下程式碼來源於一個基於 beego 的開源部落格: - -```Go - -//登陸處理 -func (this *LoginController) Post() { - this.TplNames = "login.tpl" - this.Ctx.Request.ParseForm() - username := this.Ctx.Request.Form.Get("username") - password := this.Ctx.Request.Form.Get("password") - md5Password := md5.New() - io.WriteString(md5Password, password) - buffer := bytes.NewBuffer(nil) - fmt.Fprintf(buffer, "%x", md5Password.Sum(nil)) - newPass := buffer.String() - - now := time.Now().Format("2006-01-02 15:04:05") - - userInfo := models.GetUserInfo(username) - if userInfo.Password == newPass { - var users models.User - users.Last_logintime = now - models.UpdateUserInfo(users) - - //登入成功設定 session - - sess := globalSessions.SessionStart(this.Ctx.ResponseWriter, this.Ctx.Request) - sess.Set("uid", userInfo.Id) - sess.Set("uname", userInfo.Username) - - this.Ctx.Redirect(302, "/") - } -} - -//註冊處理 -func (this *RegController) Post() { - this.TplNames = "reg.tpl" - this.Ctx.Request.ParseForm() - username := this.Ctx.Request.Form.Get("username") - password := this.Ctx.Request.Form.Get("password") - usererr := checkUsername(username) - fmt.Println(usererr) - if usererr == false { - this.Data["UsernameErr"] = "Username error, Please to again" - return - } - - passerr := checkPassword(password) - if passerr == false { - this.Data["PasswordErr"] = "Password error, Please to again" - return - } - - md5Password := md5.New() - io.WriteString(md5Password, password) - buffer := bytes.NewBuffer(nil) - fmt.Fprintf(buffer, "%x", md5Password.Sum(nil)) - newPass := buffer.String() - - now := time.Now().Format("2006-01-02 15:04:05") - - userInfo := models.GetUserInfo(username) - - if userInfo.Username == "" { - var users models.User - users.Username = username - users.Password = newPass - users.Created = now - users.Last_logintime = now - models.AddUser(users) - - //登入成功設定 session - - sess := globalSessions.SessionStart(this.Ctx.ResponseWriter, this.Ctx.Request) - sess.Set("uid", userInfo.Id) - sess.Set("uname", userInfo.Username) - this.Ctx.Redirect(302, "/") - } else { - this.Data["UsernameErr"] = "User already exists" - } - -} - -func checkPassword(password string) (b bool) { - if ok, _ := regexp.MatchString("^[a-zA-Z0-9]{4,16}$", password); !ok { - return false - } - return true -} - -func checkUsername(username string) (b bool) { - if ok, _ := regexp.MatchString("^[a-zA-Z0-9]{4,16}$", username); !ok { - return false - } - return true -} -``` -有了使用者登陸和註冊之後,其他模組的地方可以增加如下這樣的使用者是否登陸的判斷: - -```Go - -func (this *AddBlogController) Prepare() { - sess := globalSessions.SessionStart(this.Ctx.ResponseWriter, this.Ctx.Request) - sess_uid := sess.Get("userid") - sess_username := sess.Get("username") - if sess_uid == nil { - this.Ctx.Redirect(302, "/admin/login") - return - } - this.Data["Username"] = sess_username -} -``` -## links - * [目錄]() - * 上一節: [表單及驗證支援](<14.3.md>) - * 下一節: [多語言支援](<14.5.md>) \ No newline at end of file +# 14.4 使用者認證 +在開發 Web 應用過程中,使用者認證是開發者經常遇到的問題,使用者登入、註冊、登出等操作,而一般認證也分為三個方面的認證 + +- HTTP Basic 和 HTTP Digest 認證 +- 第三方整合認證:QQ、微博、豆瓣、OPENID、google、GitHub、facebook 和 twitter 等 +- 自訂的使用者登入、註冊、登出,一般都是基於 session、cookie 認證 + +beego 目前沒有針對這三種方式進行任何形式的整合,但是可以充分的利用第三方開源函式庫來實現上面的三種方式的使用者認證,不過後續 beego 會對前面兩種認證逐步整合。 + +## HTTP Basic 和 HTTP Digest 認證 +這兩個認證是一些應用採用的比較簡單的認證,目前已經有開源的第三方函式庫支援這兩個認證: + +```Go + +github.com/abbot/go-http-auth +``` +下面程式碼示範了如何把這個函式庫引入 beego 中從而實現認證: + +```Go + +package controllers + +import ( + "github.com/abbot/go-http-auth" + "github.com/astaxie/beego" +) + +func Secret(user, realm string) string { + if user == "john" { + // password is "hello" + return "$1$dlPL2MqE$oQmn16q49SqdmhenQuNgs1" + } + return "" +} + +type MainController struct { + beego.Controller +} + +func (this *MainController) Prepare() { + a := auth.NewBasicAuthenticator("example.com", Secret) + if username := a.CheckAuth(this.Ctx.Request); username == "" { + a.RequireAuth(this.Ctx.ResponseWriter, this.Ctx.Request) + } +} + +func (this *MainController) Get() { + this.Data["Username"] = "astaxie" + this.Data["Email"] = "astaxie@gmail.com" + this.TplNames = "index.tpl" +} +``` +上面程式碼利用了 beego 的 prepare 函式,在執行正常邏輯之前呼叫了認證函式,這樣就非常簡單的實現了 http auth,digest 的認證也是同樣的原理。 + +## oauth 和 oauth2 的認證 +oauth 和 oauth2 是目前比較流行的兩種認證方式,還好第三方有一個函式庫實現了這個認證,但是是國外實現的,並沒有 QQ、微博之類別的國內應用認證整合: + +```Go + +github.com/bradrydzewski/go.auth +``` +下面程式碼示範了如何把該函式庫引入 beego 中從而實現 oauth 的認證,這裡以 GitHub 為例示範: + +1. 新增兩條路由 + +```Go + +beego.RegisterController("/auth/login", &controllers.GithubController{}) +beego.RegisterController("/mainpage", &controllers.PageController{}) +``` +2. 然後我們處理 GithubController 登陸的頁面: + +```Go +package controllers + +import ( + "github.com/astaxie/beego" + "github.com/bradrydzewski/go.auth" +) + +const ( + githubClientKey = "a0864ea791ce7e7bd0df" + githubSecretKey = "a0ec09a647a688a64a28f6190b5a0d2705df56ca" +) + +type GithubController struct { + beego.Controller +} + +func (this *GithubController) Get() { + // set the auth parameters + auth.Config.CookieSecret = []byte("7H9xiimk2QdTdYI7rDddfJeV") + auth.Config.LoginSuccessRedirect = "/mainpage" + auth.Config.CookieSecure = false + + githubHandler := auth.Github(githubClientKey, githubSecretKey) + + githubHandler.ServeHTTP(this.Ctx.ResponseWriter, this.Ctx.Request) +} +``` + +3. 處理登陸成功之後的頁面 + +```Go +package controllers + +import ( + "github.com/astaxie/beego" + "github.com/bradrydzewski/go.auth" + "net/http" + "net/url" +) + +type PageController struct { + beego.Controller +} + +func (this *PageController) Get() { + // set the auth parameters + auth.Config.CookieSecret = []byte("7H9xiimk2QdTdYI7rDddfJeV") + auth.Config.LoginSuccessRedirect = "/mainpage" + auth.Config.CookieSecure = false + + user, err := auth.GetUserCookie(this.Ctx.Request) + + //if no active user session then authorize user + if err != nil || user.Id() == "" { + http.Redirect(this.Ctx.ResponseWriter, this.Ctx.Request, auth.Config.LoginRedirect, http.StatusSeeOther) + return + } + + //else, add the user to the URL and continue + this.Ctx.Request.URL.User = url.User(user.Id()) + this.Data["pic"] = user.Picture() + this.Data["id"] = user.Id() + this.Data["name"] = user.Name() + this.TplNames = "home.tpl" +} +``` + +整個的流程如下,首先開啟瀏覽器輸入地址: + +![](images/14.4.github.png) + +圖 14.4 顯示帶有登入按鈕的首頁 + +然後點選連結出現如下介面: + +![](images/14.4.github2.png) + +圖 14.5 點選登入按鈕後顯示 GitHub 的授權頁 + +然後點選 Authorize app 就出現如下介面: + +![](images/14.4.github3.png) + +圖 14.6 授權登入之後顯示的取得到的 GitHub 資訊頁 + +## 自訂認證 +自訂的認證一般都是和 session 結合驗證的,如下程式碼來源於一個基於 beego 的開源部落格: + +```Go + +//登陸處理 +func (this *LoginController) Post() { + this.TplNames = "login.tpl" + this.Ctx.Request.ParseForm() + username := this.Ctx.Request.Form.Get("username") + password := this.Ctx.Request.Form.Get("password") + md5Password := md5.New() + io.WriteString(md5Password, password) + buffer := bytes.NewBuffer(nil) + fmt.Fprintf(buffer, "%x", md5Password.Sum(nil)) + newPass := buffer.String() + + now := time.Now().Format("2006-01-02 15:04:05") + + userInfo := models.GetUserInfo(username) + if userInfo.Password == newPass { + var users models.User + users.Last_logintime = now + models.UpdateUserInfo(users) + + //登入成功設定 session + + sess := globalSessions.SessionStart(this.Ctx.ResponseWriter, this.Ctx.Request) + sess.Set("uid", userInfo.Id) + sess.Set("uname", userInfo.Username) + + this.Ctx.Redirect(302, "/") + } +} + +//註冊處理 +func (this *RegController) Post() { + this.TplNames = "reg.tpl" + this.Ctx.Request.ParseForm() + username := this.Ctx.Request.Form.Get("username") + password := this.Ctx.Request.Form.Get("password") + usererr := checkUsername(username) + fmt.Println(usererr) + if usererr == false { + this.Data["UsernameErr"] = "Username error, Please to again" + return + } + + passerr := checkPassword(password) + if passerr == false { + this.Data["PasswordErr"] = "Password error, Please to again" + return + } + + md5Password := md5.New() + io.WriteString(md5Password, password) + buffer := bytes.NewBuffer(nil) + fmt.Fprintf(buffer, "%x", md5Password.Sum(nil)) + newPass := buffer.String() + + now := time.Now().Format("2006-01-02 15:04:05") + + userInfo := models.GetUserInfo(username) + + if userInfo.Username == "" { + var users models.User + users.Username = username + users.Password = newPass + users.Created = now + users.Last_logintime = now + models.AddUser(users) + + //登入成功設定 session + + sess := globalSessions.SessionStart(this.Ctx.ResponseWriter, this.Ctx.Request) + sess.Set("uid", userInfo.Id) + sess.Set("uname", userInfo.Username) + this.Ctx.Redirect(302, "/") + } else { + this.Data["UsernameErr"] = "User already exists" + } + +} + +func checkPassword(password string) (b bool) { + if ok, _ := regexp.MatchString("^[a-zA-Z0-9]{4,16}$", password); !ok { + return false + } + return true +} + +func checkUsername(username string) (b bool) { + if ok, _ := regexp.MatchString("^[a-zA-Z0-9]{4,16}$", username); !ok { + return false + } + return true +} +``` +有了使用者登陸和註冊之後,其他模組的地方可以增加如下這樣的使用者是否登陸的判斷: + +```Go + +func (this *AddBlogController) Prepare() { + sess := globalSessions.SessionStart(this.Ctx.ResponseWriter, this.Ctx.Request) + sess_uid := sess.Get("userid") + sess_username := sess.Get("username") + if sess_uid == nil { + this.Ctx.Redirect(302, "/admin/login") + return + } + this.Data["Username"] = sess_username +} +``` +## links + * [目錄]() + * 上一節: [表單及驗證支援](<14.3.md>) + * 下一節: [多語言支援](<14.5.md>) diff --git a/zh-tw/build_new.go b/zh-tw/build_new.go index a11f375a..b3e04c11 100644 --- a/zh-tw/build_new.go +++ b/zh-tw/build_new.go @@ -11,7 +11,7 @@ import ( "strings" ) -// 开发者 github token +// 开发者 GitHub token const token = "" // 定义一个访问者结构体 diff --git a/zh/01.2.md b/zh/01.2.md index 51bf0f09..c99b6881 100644 --- a/zh/01.2.md +++ b/zh/01.2.md @@ -1,181 +1,181 @@ -# 1.2 GOPATH与工作空间 - -前面我们在安装Go的时候看到需要设置GOPATH变量,Go从1.1版本到1.7必须设置这个变量,而且不能和Go的安装目录一样,这个目录用来存放Go源码,Go的可运行文件,以及相应的编译之后的包文件。所以这个目录下面有三个子目录:src、bin、pkg - -从go 1.8开始,GOPATH环境变量现在有一个默认值,如果它没有被设置。 它在Unix上默认为$HOME/go,在Windows上默认为%USERPROFILE%/go。 -## GOPATH设置 - go 命令依赖一个重要的环境变量:$GOPATH - - Windows系统中环境变量的形式为`%GOPATH%`,本书主要使用Unix形式,Windows用户请自行替换。 - - *(注:这个不是Go安装目录。下面以笔者的工作目录为示例,如果你想不一样请把GOPATH替换成你的工作目录。)* - - 在类 Unix 环境下大概这样设置: -```sh -export GOPATH=/home/apple/mygo -``` - 为了方便,应该新建以上文件夹,并且上一行加入到 `.bashrc` 或者 `.zshrc` 或者自己的 `sh` 的配置文件中。 - - Windows 设置如下,新建一个环境变量名称叫做GOPATH: -```sh -GOPATH=c:\mygo -``` -GOPATH允许多个目录,当有多个目录时,请注意分隔符,多个目录的时候Windows是分号,Linux系统是冒号,当有多个GOPATH时,默认会将go get的内容放在第一个目录下。 - - -以上 $GOPATH 目录约定有三个子目录: - -- src 存放源代码(比如:.go .c .h .s等) -- pkg 编译后生成的文件(比如:.a) -- bin 编译后生成的可执行文件(为了方便,可以把此目录加入到 $PATH 变量中,如果有多个gopath,那么使用`${GOPATH//://bin:}/bin`添加所有的bin目录) - -以后我所有的例子都是以mygo作为我的gopath目录 - - -## 代码目录结构规划 -GOPATH下的src目录就是接下来开发程序的主要目录,所有的源码都是放在这个目录下面,那么一般我们的做法就是一个目录一个项目,例如: $GOPATH/src/mymath 表示mymath这个应用包或者可执行应用,这个根据package是main还是其他来决定,main的话就是可执行应用,其他的话就是应用包,这个会在后续详细介绍package。 - - -所以当新建应用或者一个代码包时都是在src目录下新建一个文件夹,文件夹名称一般是代码包名称,当然也允许多级目录,例如在src下面新建了目录$GOPATH/src/github.com/astaxie/beedb 那么这个包路径就是"github.com/astaxie/beedb",包名称是最后一个目录beedb - -下面我就以mymath为例来讲述如何编写应用包,执行如下代码 -```sh -cd $GOPATH/src -mkdir mymath -``` - -新建文件sqrt.go,内容如下 -```go -// $GOPATH/src/mymath/sqrt.go源码如下: -package mymath - -func Sqrt(x float64) float64 { - z := 0.0 - for i := 0; i < 1000; i++ { - z -= (z*z - x) / (2 * x) - } - return z -} -``` -这样我的应用包目录和代码已经新建完毕,注意:一般建议package的名称和目录名保持一致 - -## 编译应用 -上面我们已经建立了自己的应用包,如何进行编译安装呢?有两种方式可以进行安装 - -1、只要进入对应的应用包目录,然后执行`go install`,就可以安装了 - -2、在任意的目录执行如下代码`go install mymath` - -安装完之后,我们可以进入如下目录 -```sh -cd $GOPATH/pkg/${GOOS}_${GOARCH} -//可以看到如下文件 -mymath.a -``` -这个.a文件是应用包,那么我们如何进行调用呢? - -接下来我们新建一个应用程序来调用这个应用包 - -新建应用包mathapp -```sh -cd $GOPATH/src -mkdir mathapp -cd mathapp -vim main.go -``` - -`$GOPATH/src/mathapp/main.go`源码: -```go -package main - -import ( - "mymath" - "fmt" -) - -func main() { - fmt.Printf("Hello, world. Sqrt(2) = %v\n", mymath.Sqrt(2)) -} -``` - -可以看到这个的package是`main`,import里面调用的包是`mymath`,这个就是相对于`$GOPATH/src`的路径,如果是多级目录,就在import里面引入多级目录,如果你有多个GOPATH,也是一样,Go会自动在多个`$GOPATH/src`中寻找。 - -如何编译程序呢?进入该应用目录,然后执行`go build`,那么在该目录下面会生成一个mathapp的可执行文件 -```sh -./mathapp -``` - -输出如下内容 -```sh -Hello, world. Sqrt(2) = 1.414213562373095 -``` - -如何安装该应用,进入该目录执行`go install`,那么在$GOPATH/bin/下增加了一个可执行文件mathapp, 还记得前面我们把`$GOPATH/bin`加到我们的PATH里面了,这样可以在命令行输入如下命令就可以执行 - -```sh -mathapp -``` - -也是输出如下内容 - - Hello, world. Sqrt(2) = 1.414213562373095 - -这里我们展示如何编译和安装一个可运行的应用,以及如何设计我们的目录结构。 - -## 获取远程包 - go语言有一个获取远程包的工具就是`go get`,目前go get支持多数开源社区(例如:github、googlecode、bitbucket、Launchpad) - - go get github.com/astaxie/beedb - ->go get -u 参数可以自动更新包,而且当go get的时候会自动获取该包依赖的其他第三方包 - -通过这个命令可以获取相应的源码,对应的开源平台采用不同的源码控制工具,例如github采用git、googlecode采用hg,所以要想获取这些源码,必须先安装相应的源码控制工具 - -通过上面获取的代码在我们本地的源码相应的代码结构如下 - - $GOPATH - src - |--github.com - |-astaxie - |-beedb - pkg - |--相应平台 - |-github.com - |--astaxie - |beedb.a - -go get本质上可以理解为首先第一步是通过源码工具clone代码到src下面,然后执行`go install` - -在代码中如何使用远程包,很简单的就是和使用本地包一样,只要在开头import相应的路径就可以 - - import "github.com/astaxie/beedb" - -## 程序的整体结构 -通过上面建立的我本地的mygo的目录结构如下所示 - - bin/ - mathapp - pkg/ - 平台名/ 如:darwin_amd64、linux_amd64 - mymath.a - github.com/ - astaxie/ - beedb.a - src/ - mathapp - main.go - mymath/ - sqrt.go - github.com/ - astaxie/ - beedb/ - beedb.go - util.go - -从上面的结构我们可以很清晰的看到,bin目录下面存的是编译之后可执行的文件,pkg下面存放的是应用包,src下面保存的是应用源代码 - - -## links - * [目录]() - * 上一节: [安装Go](<01.1.md>) - * 下一节: [GO 命令](<01.3.md>) +# 1.2 GOPATH与工作空间 + +前面我们在安装Go的时候看到需要设置GOPATH变量,Go从1.1版本到1.7必须设置这个变量,而且不能和Go的安装目录一样,这个目录用来存放Go源码,Go的可运行文件,以及相应的编译之后的包文件。所以这个目录下面有三个子目录:src、bin、pkg + +从go 1.8开始,GOPATH环境变量现在有一个默认值,如果它没有被设置。 它在Unix上默认为$HOME/go,在Windows上默认为%USERPROFILE%/go。 +## GOPATH设置 + go 命令依赖一个重要的环境变量:$GOPATH + + Windows系统中环境变量的形式为`%GOPATH%`,本书主要使用Unix形式,Windows用户请自行替换。 + + *(注:这个不是Go安装目录。下面以笔者的工作目录为示例,如果你想不一样请把GOPATH替换成你的工作目录。)* + + 在类 Unix 环境下大概这样设置: +```sh +export GOPATH=/home/apple/mygo +``` + 为了方便,应该新建以上文件夹,并且上一行加入到 `.bashrc` 或者 `.zshrc` 或者自己的 `sh` 的配置文件中。 + + Windows 设置如下,新建一个环境变量名称叫做GOPATH: +```sh +GOPATH=c:\mygo +``` +GOPATH允许多个目录,当有多个目录时,请注意分隔符,多个目录的时候Windows是分号,Linux系统是冒号,当有多个GOPATH时,默认会将go get的内容放在第一个目录下。 + + +以上 $GOPATH 目录约定有三个子目录: + +- src 存放源代码(比如:.go .c .h .s等) +- pkg 编译后生成的文件(比如:.a) +- bin 编译后生成的可执行文件(为了方便,可以把此目录加入到 $PATH 变量中,如果有多个gopath,那么使用`${GOPATH//://bin:}/bin`添加所有的bin目录) + +以后我所有的例子都是以mygo作为我的gopath目录 + + +## 代码目录结构规划 +GOPATH下的src目录就是接下来开发程序的主要目录,所有的源码都是放在这个目录下面,那么一般我们的做法就是一个目录一个项目,例如: $GOPATH/src/mymath 表示mymath这个应用包或者可执行应用,这个根据package是main还是其他来决定,main的话就是可执行应用,其他的话就是应用包,这个会在后续详细介绍package。 + + +所以当新建应用或者一个代码包时都是在src目录下新建一个文件夹,文件夹名称一般是代码包名称,当然也允许多级目录,例如在src下面新建了目录$GOPATH/src/github.com/astaxie/beedb 那么这个包路径就是"github.com/astaxie/beedb",包名称是最后一个目录beedb + +下面我就以mymath为例来讲述如何编写应用包,执行如下代码 +```sh +cd $GOPATH/src +mkdir mymath +``` + +新建文件sqrt.go,内容如下 +```go +// $GOPATH/src/mymath/sqrt.go源码如下: +package mymath + +func Sqrt(x float64) float64 { + z := 0.0 + for i := 0; i < 1000; i++ { + z -= (z*z - x) / (2 * x) + } + return z +} +``` +这样我的应用包目录和代码已经新建完毕,注意:一般建议package的名称和目录名保持一致 + +## 编译应用 +上面我们已经建立了自己的应用包,如何进行编译安装呢?有两种方式可以进行安装 + +1、只要进入对应的应用包目录,然后执行`go install`,就可以安装了 + +2、在任意的目录执行如下代码`go install mymath` + +安装完之后,我们可以进入如下目录 +```sh +cd $GOPATH/pkg/${GOOS}_${GOARCH} +//可以看到如下文件 +mymath.a +``` +这个.a文件是应用包,那么我们如何进行调用呢? + +接下来我们新建一个应用程序来调用这个应用包 + +新建应用包mathapp +```sh +cd $GOPATH/src +mkdir mathapp +cd mathapp +vim main.go +``` + +`$GOPATH/src/mathapp/main.go`源码: +```go +package main + +import ( + "mymath" + "fmt" +) + +func main() { + fmt.Printf("Hello, world. Sqrt(2) = %v\n", mymath.Sqrt(2)) +} +``` + +可以看到这个的package是`main`,import里面调用的包是`mymath`,这个就是相对于`$GOPATH/src`的路径,如果是多级目录,就在import里面引入多级目录,如果你有多个GOPATH,也是一样,Go会自动在多个`$GOPATH/src`中寻找。 + +如何编译程序呢?进入该应用目录,然后执行`go build`,那么在该目录下面会生成一个mathapp的可执行文件 +```sh +./mathapp +``` + +输出如下内容 +```sh +Hello, world. Sqrt(2) = 1.414213562373095 +``` + +如何安装该应用,进入该目录执行`go install`,那么在$GOPATH/bin/下增加了一个可执行文件mathapp, 还记得前面我们把`$GOPATH/bin`加到我们的PATH里面了,这样可以在命令行输入如下命令就可以执行 + +```sh +mathapp +``` + +也是输出如下内容 + + Hello, world. Sqrt(2) = 1.414213562373095 + +这里我们展示如何编译和安装一个可运行的应用,以及如何设计我们的目录结构。 + +## 获取远程包 + go语言有一个获取远程包的工具就是`go get`,目前go get支持多数开源社区(例如:GitHub、googlecode、bitbucket、Launchpad) + + go get github.com/astaxie/beedb + +>go get -u 参数可以自动更新包,而且当go get的时候会自动获取该包依赖的其他第三方包 + +通过这个命令可以获取相应的源码,对应的开源平台采用不同的源码控制工具,例如GitHub采用git、googlecode采用hg,所以要想获取这些源码,必须先安装相应的源码控制工具 + +通过上面获取的代码在我们本地的源码相应的代码结构如下 + + $GOPATH + src + |--github.com + |-astaxie + |-beedb + pkg + |--相应平台 + |-github.com + |--astaxie + |beedb.a + +go get本质上可以理解为首先第一步是通过源码工具clone代码到src下面,然后执行`go install` + +在代码中如何使用远程包,很简单的就是和使用本地包一样,只要在开头import相应的路径就可以 + + import "github.com/astaxie/beedb" + +## 程序的整体结构 +通过上面建立的我本地的mygo的目录结构如下所示 + + bin/ + mathapp + pkg/ + 平台名/ 如:darwin_amd64、linux_amd64 + mymath.a + github.com/ + astaxie/ + beedb.a + src/ + mathapp + main.go + mymath/ + sqrt.go + github.com/ + astaxie/ + beedb/ + beedb.go + util.go + +从上面的结构我们可以很清晰的看到,bin目录下面存的是编译之后可执行的文件,pkg下面存放的是应用包,src下面保存的是应用源代码 + + +## links + * [目录]() + * 上一节: [安装Go](<01.1.md>) + * 下一节: [GO 命令](<01.3.md>) diff --git a/zh/01.3.md b/zh/01.3.md index 8ae51727..d3bc806e 100644 --- a/zh/01.3.md +++ b/zh/01.3.md @@ -1,204 +1,204 @@ -# 1.3 Go 命令 - -## Go 命令 - - Go语言自带有一套完整的命令操作工具,你可以通过在命令行中执行`go`来查看它们: - - ![](images/1.1.mac.png?raw=true) - -图1.3 Go命令显示详细的信息 - - 这些命令对于我们平时编写的代码非常有用,接下来就让我们了解一些常用的命令。 - -## go build - - 这个命令主要用于编译代码。在包的编译过程中,若有必要,会同时编译与之相关联的包。 - - - 如果是普通包,就像我们在1.2节中编写的`mymath`包那样,当你执行`go build`之后,它不会产生任何文件。如果你需要在`$GOPATH/pkg`下生成相应的文件,那就得执行`go install`。 - - - 如果是`main`包,当你执行`go build`之后,它就会在当前目录下生成一个可执行文件。如果你需要在`$GOPATH/bin`下生成相应的文件,需要执行`go install`,或者使用`go build -o 路径/a.exe`。 - - - 如果某个项目文件夹下有多个文件,而你只想编译某个文件,就可在`go build`之后加上文件名,例如`go build a.go`;`go build`命令默认会编译当前目录下的所有go文件。 - - - 你也可以指定编译输出的文件名。例如1.2节中的`mathapp`应用,我们可以指定`go build -o astaxie.exe`,默认情况是你的package名(非main包),或者是第一个源文件的文件名(main包)。 - - (注:实际上,package名在[Go语言规范](https://golang.org/ref/spec)中指代码中“package”后使用的名称,此名称可以与文件夹名不同。默认生成的可执行文件名是文件夹名。) - - - go build会忽略目录下以“_”或“.”开头的go文件。 - - - 如果你的源代码针对不同的操作系统需要不同的处理,那么你可以根据不同的操作系统后缀来命名文件。例如有一个读取数组的程序,它对于不同的操作系统可能有如下几个源文件: - - array_linux.go - array_darwin.go - array_windows.go - array_freebsd.go - - `go build`的时候会选择性地编译以系统名结尾的文件(Linux、Darwin、Windows、Freebsd)。例如Linux系统下面编译只会选择array_linux.go文件,其它系统命名后缀文件全部忽略。 - -参数的介绍 - -- `-o` 指定输出的文件名,可以带上路径,例如 `go build -o a/b/c` -- `-i` 安装相应的包,编译+`go install` -- `-a` 更新全部已经是最新的包的,但是对标准包不适用 -- `-n` 把需要执行的编译命令打印出来,但是不执行,这样就可以很容易的知道底层是如何运行的 -- `-p n` 指定可以并行可运行的编译数目,默认是CPU数目 -- `-race` 开启编译的时候自动检测数据竞争的情况,目前只支持64位的机器 -- `-v` 打印出来我们正在编译的包名 -- `-work` 打印出来编译时候的临时文件夹名称,并且如果已经存在的话就不要删除 -- `-x` 打印出来执行的命令,其实就是和`-n`的结果类似,只是这个会执行 -- `-ccflags 'arg list'` 传递参数给5c, 6c, 8c 调用 -- `-compiler name` 指定相应的编译器,gccgo还是gc -- `-gccgoflags 'arg list'` 传递参数给gccgo编译连接调用 -- `-gcflags 'arg list'` 传递参数给5g, 6g, 8g 调用 -- `-installsuffix suffix` 为了和默认的安装包区别开来,采用这个前缀来重新安装那些依赖的包,`-race`的时候默认已经是`-installsuffix race`,大家可以通过`-n`命令来验证 -- `-ldflags 'flag list'` 传递参数给5l, 6l, 8l 调用 -- `-tags 'tag list'` 设置在编译的时候可以适配的那些tag,详细的tag限制参考里面的 [Build Constraints](http://golang.org/pkg/go/build/) - -## go clean - - 这个命令是用来移除当前源码包和关联源码包里面编译生成的文件。这些文件包括 - - _obj/ 旧的object目录,由Makefiles遗留 - _test/ 旧的test目录,由Makefiles遗留 - _testmain.go 旧的gotest文件,由Makefiles遗留 - test.out 旧的test记录,由Makefiles遗留 - build.out 旧的test记录,由Makefiles遗留 - *.[568ao] object文件,由Makefiles遗留 - - DIR(.exe) 由go build产生 - DIR.test(.exe) 由go test -c产生 - MAINFILE(.exe) 由go build MAINFILE.go产生 - *.so 由 SWIG 产生 - - 我一般都是利用这个命令清除编译文件,然后github递交源码,在本机测试的时候这些编译文件都是和系统相关的,但是对于源码管理来说没必要。 - - $ go clean -i -n - cd /Users/astaxie/develop/gopath/src/mathapp - rm -f mathapp mathapp.exe mathapp.test mathapp.test.exe app app.exe - rm -f /Users/astaxie/develop/gopath/bin/mathapp - -参数介绍 - -- `-i` 清除关联的安装的包和可运行文件,也就是通过go install安装的文件 -- `-n` 把需要执行的清除命令打印出来,但是不执行,这样就可以很容易的知道底层是如何运行的 -- `-r` 循环的清除在import中引入的包 -- `-x` 打印出来执行的详细命令,其实就是`-n`打印的执行版本 - -## go fmt - - 有过C/C++经验的读者会知道,一些人经常为代码采取K&R风格还是ANSI风格而争论不休。在go中,代码则有标准的风格。由于之前已经有的一些习惯或其它的原因我们常将代码写成ANSI风格或者其它更合适自己的格式,这将为人们在阅读别人的代码时添加不必要的负担,所以go强制了代码格式(比如左大括号必须放在行尾),不按照此格式的代码将不能编译通过,为了减少浪费在排版上的时间,go工具集中提供了一个`go fmt`命令 它可以帮你格式化你写好的代码文件,使你写代码的时候不需要关心格式,你只需要在写完之后执行`go fmt <文件名>.go`,你的代码就被修改成了标准格式,但是我平常很少用到这个命令,因为开发工具里面一般都带了保存时候自动格式化功能,这个功能其实在底层就是调用了`go fmt`。接下来的一节我将讲述两个工具,这两个工具都自带了保存文件时自动化`go fmt`功能。 - -使用go fmt命令,其实是调用了gofmt,而且需要参数-w,否则格式化结果不会写入文件。gofmt -w -l src,可以格式化整个项目。 - -所以go fmt是gofmt的上层一个包装的命令,我们想要更多的个性化的格式化可以参考 [gofmt](http://golang.org/cmd/gofmt/) - -gofmt的参数介绍 - -- `-l` 显示那些需要格式化的文件 -- `-w` 把改写后的内容直接写入到文件中,而不是作为结果打印到标准输出。 -- `-r` 添加形如“a[b:len(a)] -> a[b:]”的重写规则,方便我们做批量替换 -- `-s` 简化文件中的代码 -- `-d` 显示格式化前后的diff而不是写入文件,默认是false -- `-e` 打印所有的语法错误到标准输出。如果不使用此标记,则只会打印不同行的前10个错误。 -- `-cpuprofile` 支持调试模式,写入相应的cpufile到指定的文件 - -## go get - - 这个命令是用来动态获取远程代码包的,目前支持的有BitBucket、GitHub、Google Code和Launchpad。这个命令在内部实际上分成了两步操作:第一步是下载源码包,第二步是执行`go install`。下载源码包的go工具会自动根据不同的域名调用不同的源码工具,对应关系如下: - - BitBucket (Mercurial Git) - GitHub (Git) - Google Code Project Hosting (Git, Mercurial, Subversion) - Launchpad (Bazaar) - - 所以为了`go get` 能正常工作,你必须确保安装了合适的源码管理工具,并同时把这些命令加入你的PATH中。其实`go get`支持自定义域名的功能,具体参见`go help remote`。 - -参数介绍: - -- `-d` 只下载不安装 -- `-f` 只有在你包含了`-u`参数的时候才有效,不让`-u`去验证import中的每一个都已经获取了,这对于本地fork的包特别有用 -- `-fix` 在获取源码之后先运行fix,然后再去做其他的事情 -- `-t` 同时也下载需要为运行测试所需要的包 -- `-u` 强制使用网络去更新包和它的依赖包 -- `-v` 显示执行的命令 - -## go install - - 这个命令在内部实际上分成了两步操作:第一步是生成结果文件(可执行文件或者.a包),第二步会把编译好的结果移到`$GOPATH/pkg`或者`$GOPATH/bin`。 - -参数支持`go build`的编译参数。大家只要记住一个参数`-v`就好了,这个随时随地的可以查看底层的执行信息。 - -## go test - - 执行这个命令,会自动读取源码目录下面名为`*_test.go`的文件,生成并运行测试用的可执行文件。输出的信息类似 - - ok archive/tar 0.011s - FAIL archive/zip 0.022s - ok compress/gzip 0.033s - ... - - 默认的情况下,不需要任何的参数,它会自动把你源码包下面所有test文件测试完毕,当然你也可以带上参数,详情请参考`go help testflag` - -这里我介绍几个我们常用的参数: - -- `-bench regexp` 执行相应的benchmarks,例如 `-bench=.` -- `-cover` 开启测试覆盖率 -- `-run regexp` 只运行regexp匹配的函数,例如 `-run=Array` 那么就执行包含有Array开头的函数 -- `-v` 显示测试的详细命令 - -## go tool -`go tool`下面下载聚集了很多命令,这里我们只介绍两个,fix和vet - -- `go tool fix .` 用来修复以前老版本的代码到新版本,例如go1之前老版本的代码转化到go1,例如API的变化 -- `go tool vet directory|files` 用来分析当前目录的代码是否都是正确的代码,例如是不是调用fmt.Printf里面的参数不正确,例如函数里面提前return了然后出现了无用代码之类的。 - -## go generate -这个命令是从Go1.4开始才设计的,用于在编译前自动化生成某类代码。`go generate`和`go build`是完全不一样的命令,通过分析源码中特殊的注释,然后执行相应的命令。这些命令都是很明确的,没有任何的依赖在里面。而且大家在用这个之前心里面一定要有一个理念,这个`go generate`是给你用的,不是给使用你这个包的人用的,是方便你来生成一些代码的。 - -这里我们来举一个简单的例子,例如我们经常会使用`yacc`来生成代码,那么我们常用这样的命令: - - go tool yacc -o gopher.go -p parser gopher.y - --o 指定了输出的文件名, -p指定了package的名称,这是一个单独的命令,如果我们想让`go generate`来触发这个命令,那么就可以在当前目录的任意一个`xxx.go`文件里面的任意位置增加一行如下的注释: - - //go:generate go tool yacc -o gopher.go -p parser gopher.y - -这里我们注意了,`//go:generate`是没有任何空格的,这其实就是一个固定的格式,在扫描源码文件的时候就是根据这个来判断的。 - -所以我们可以通过如下的命令来生成,编译,测试。如果`gopher.y`文件有修改,那么就重新执行`go generate`重新生成文件就好。 - - $ go generate - $ go build - $ go test - - -## godoc - -在Go1.2版本之前还支持`go doc`命令,但是之后全部移到了godoc这个命令下,需要这样安装`go get golang.org/x/tools/cmd/godoc` - - 很多人说go不需要任何的第三方文档,例如chm手册之类的(其实我已经做了一个了,[chm手册](https://github.com/astaxie/godoc)),因为它内部就有一个很强大的文档工具。 - - 如何查看相应package的文档呢? - 例如builtin包,那么执行`godoc builtin` - 如果是http包,那么执行`godoc net/http` - 查看某一个包里面的函数,那么执行`godoc fmt Printf` - 也可以查看相应的代码,执行`godoc -src fmt Printf` - - 通过命令在命令行执行 godoc -http=:端口号 比如`godoc -http=:8080`。然后在浏览器中打开`127.0.0.1:8080`,你将会看到一个golang.org的本地copy版本,通过它你可以查询pkg文档等其它内容。如果你设置了GOPATH,在pkg分类下,不但会列出标准包的文档,还会列出你本地`GOPATH`中所有项目的相关文档,这对于经常被墙的用户来说是一个不错的选择。 - -## 其它命令 - - go还提供了其它很多的工具,例如下面的这些工具 - - go version 查看go当前的版本 - go env 查看当前go的环境变量 - go list 列出当前全部安装的package - go run 编译并运行Go程序 - -以上这些工具还有很多参数没有一一介绍,用户可以使用`go help 命令`获取更详细的帮助信息。 - - -## links - * [目录]() - * 上一节: [GOPATH与工作空间](<01.2.md>) - * 下一节: [Go开发工具](<01.4.md>) +# 1.3 Go 命令 + +## Go 命令 + + Go语言自带有一套完整的命令操作工具,你可以通过在命令行中执行`go`来查看它们: + + ![](images/1.1.mac.png?raw=true) + +图1.3 Go命令显示详细的信息 + + 这些命令对于我们平时编写的代码非常有用,接下来就让我们了解一些常用的命令。 + +## go build + + 这个命令主要用于编译代码。在包的编译过程中,若有必要,会同时编译与之相关联的包。 + + - 如果是普通包,就像我们在1.2节中编写的`mymath`包那样,当你执行`go build`之后,它不会产生任何文件。如果你需要在`$GOPATH/pkg`下生成相应的文件,那就得执行`go install`。 + + - 如果是`main`包,当你执行`go build`之后,它就会在当前目录下生成一个可执行文件。如果你需要在`$GOPATH/bin`下生成相应的文件,需要执行`go install`,或者使用`go build -o 路径/a.exe`。 + + - 如果某个项目文件夹下有多个文件,而你只想编译某个文件,就可在`go build`之后加上文件名,例如`go build a.go`;`go build`命令默认会编译当前目录下的所有go文件。 + + - 你也可以指定编译输出的文件名。例如1.2节中的`mathapp`应用,我们可以指定`go build -o astaxie.exe`,默认情况是你的package名(非main包),或者是第一个源文件的文件名(main包)。 + + (注:实际上,package名在[Go语言规范](https://golang.org/ref/spec)中指代码中“package”后使用的名称,此名称可以与文件夹名不同。默认生成的可执行文件名是文件夹名。) + + - go build会忽略目录下以“_”或“.”开头的go文件。 + + - 如果你的源代码针对不同的操作系统需要不同的处理,那么你可以根据不同的操作系统后缀来命名文件。例如有一个读取数组的程序,它对于不同的操作系统可能有如下几个源文件: + + array_linux.go + array_darwin.go + array_windows.go + array_freebsd.go + + `go build`的时候会选择性地编译以系统名结尾的文件(Linux、Darwin、Windows、Freebsd)。例如Linux系统下面编译只会选择array_linux.go文件,其它系统命名后缀文件全部忽略。 + +参数的介绍 + +- `-o` 指定输出的文件名,可以带上路径,例如 `go build -o a/b/c` +- `-i` 安装相应的包,编译+`go install` +- `-a` 更新全部已经是最新的包的,但是对标准包不适用 +- `-n` 把需要执行的编译命令打印出来,但是不执行,这样就可以很容易的知道底层是如何运行的 +- `-p n` 指定可以并行可运行的编译数目,默认是CPU数目 +- `-race` 开启编译的时候自动检测数据竞争的情况,目前只支持64位的机器 +- `-v` 打印出来我们正在编译的包名 +- `-work` 打印出来编译时候的临时文件夹名称,并且如果已经存在的话就不要删除 +- `-x` 打印出来执行的命令,其实就是和`-n`的结果类似,只是这个会执行 +- `-ccflags 'arg list'` 传递参数给5c, 6c, 8c 调用 +- `-compiler name` 指定相应的编译器,gccgo还是gc +- `-gccgoflags 'arg list'` 传递参数给gccgo编译连接调用 +- `-gcflags 'arg list'` 传递参数给5g, 6g, 8g 调用 +- `-installsuffix suffix` 为了和默认的安装包区别开来,采用这个前缀来重新安装那些依赖的包,`-race`的时候默认已经是`-installsuffix race`,大家可以通过`-n`命令来验证 +- `-ldflags 'flag list'` 传递参数给5l, 6l, 8l 调用 +- `-tags 'tag list'` 设置在编译的时候可以适配的那些tag,详细的tag限制参考里面的 [Build Constraints](http://golang.org/pkg/go/build/) + +## go clean + + 这个命令是用来移除当前源码包和关联源码包里面编译生成的文件。这些文件包括 + + _obj/ 旧的object目录,由Makefiles遗留 + _test/ 旧的test目录,由Makefiles遗留 + _testmain.go 旧的gotest文件,由Makefiles遗留 + test.out 旧的test记录,由Makefiles遗留 + build.out 旧的test记录,由Makefiles遗留 + *.[568ao] object文件,由Makefiles遗留 + + DIR(.exe) 由go build产生 + DIR.test(.exe) 由go test -c产生 + MAINFILE(.exe) 由go build MAINFILE.go产生 + *.so 由 SWIG 产生 + + 我一般都是利用这个命令清除编译文件,然后GitHub递交源码,在本机测试的时候这些编译文件都是和系统相关的,但是对于源码管理来说没必要。 + + $ go clean -i -n + cd /Users/astaxie/develop/gopath/src/mathapp + rm -f mathapp mathapp.exe mathapp.test mathapp.test.exe app app.exe + rm -f /Users/astaxie/develop/gopath/bin/mathapp + +参数介绍 + +- `-i` 清除关联的安装的包和可运行文件,也就是通过go install安装的文件 +- `-n` 把需要执行的清除命令打印出来,但是不执行,这样就可以很容易的知道底层是如何运行的 +- `-r` 循环的清除在import中引入的包 +- `-x` 打印出来执行的详细命令,其实就是`-n`打印的执行版本 + +## go fmt + + 有过C/C++经验的读者会知道,一些人经常为代码采取K&R风格还是ANSI风格而争论不休。在go中,代码则有标准的风格。由于之前已经有的一些习惯或其它的原因我们常将代码写成ANSI风格或者其它更合适自己的格式,这将为人们在阅读别人的代码时添加不必要的负担,所以go强制了代码格式(比如左大括号必须放在行尾),不按照此格式的代码将不能编译通过,为了减少浪费在排版上的时间,go工具集中提供了一个`go fmt`命令 它可以帮你格式化你写好的代码文件,使你写代码的时候不需要关心格式,你只需要在写完之后执行`go fmt <文件名>.go`,你的代码就被修改成了标准格式,但是我平常很少用到这个命令,因为开发工具里面一般都带了保存时候自动格式化功能,这个功能其实在底层就是调用了`go fmt`。接下来的一节我将讲述两个工具,这两个工具都自带了保存文件时自动化`go fmt`功能。 + +使用go fmt命令,其实是调用了gofmt,而且需要参数-w,否则格式化结果不会写入文件。gofmt -w -l src,可以格式化整个项目。 + +所以go fmt是gofmt的上层一个包装的命令,我们想要更多的个性化的格式化可以参考 [gofmt](http://golang.org/cmd/gofmt/) + +gofmt的参数介绍 + +- `-l` 显示那些需要格式化的文件 +- `-w` 把改写后的内容直接写入到文件中,而不是作为结果打印到标准输出。 +- `-r` 添加形如“a[b:len(a)] -> a[b:]”的重写规则,方便我们做批量替换 +- `-s` 简化文件中的代码 +- `-d` 显示格式化前后的diff而不是写入文件,默认是false +- `-e` 打印所有的语法错误到标准输出。如果不使用此标记,则只会打印不同行的前10个错误。 +- `-cpuprofile` 支持调试模式,写入相应的cpufile到指定的文件 + +## go get + + 这个命令是用来动态获取远程代码包的,目前支持的有BitBucket、GitHub、Google Code和Launchpad。这个命令在内部实际上分成了两步操作:第一步是下载源码包,第二步是执行`go install`。下载源码包的go工具会自动根据不同的域名调用不同的源码工具,对应关系如下: + + BitBucket (Mercurial Git) + GitHub (Git) + Google Code Project Hosting (Git, Mercurial, Subversion) + Launchpad (Bazaar) + + 所以为了`go get` 能正常工作,你必须确保安装了合适的源码管理工具,并同时把这些命令加入你的PATH中。其实`go get`支持自定义域名的功能,具体参见`go help remote`。 + +参数介绍: + +- `-d` 只下载不安装 +- `-f` 只有在你包含了`-u`参数的时候才有效,不让`-u`去验证import中的每一个都已经获取了,这对于本地fork的包特别有用 +- `-fix` 在获取源码之后先运行fix,然后再去做其他的事情 +- `-t` 同时也下载需要为运行测试所需要的包 +- `-u` 强制使用网络去更新包和它的依赖包 +- `-v` 显示执行的命令 + +## go install + + 这个命令在内部实际上分成了两步操作:第一步是生成结果文件(可执行文件或者.a包),第二步会把编译好的结果移到`$GOPATH/pkg`或者`$GOPATH/bin`。 + +参数支持`go build`的编译参数。大家只要记住一个参数`-v`就好了,这个随时随地的可以查看底层的执行信息。 + +## go test + + 执行这个命令,会自动读取源码目录下面名为`*_test.go`的文件,生成并运行测试用的可执行文件。输出的信息类似 + + ok archive/tar 0.011s + FAIL archive/zip 0.022s + ok compress/gzip 0.033s + ... + + 默认的情况下,不需要任何的参数,它会自动把你源码包下面所有test文件测试完毕,当然你也可以带上参数,详情请参考`go help testflag` + +这里我介绍几个我们常用的参数: + +- `-bench regexp` 执行相应的benchmarks,例如 `-bench=.` +- `-cover` 开启测试覆盖率 +- `-run regexp` 只运行regexp匹配的函数,例如 `-run=Array` 那么就执行包含有Array开头的函数 +- `-v` 显示测试的详细命令 + +## go tool +`go tool`下面下载聚集了很多命令,这里我们只介绍两个,fix和vet + +- `go tool fix .` 用来修复以前老版本的代码到新版本,例如go1之前老版本的代码转化到go1,例如API的变化 +- `go tool vet directory|files` 用来分析当前目录的代码是否都是正确的代码,例如是不是调用fmt.Printf里面的参数不正确,例如函数里面提前return了然后出现了无用代码之类的。 + +## go generate +这个命令是从Go1.4开始才设计的,用于在编译前自动化生成某类代码。`go generate`和`go build`是完全不一样的命令,通过分析源码中特殊的注释,然后执行相应的命令。这些命令都是很明确的,没有任何的依赖在里面。而且大家在用这个之前心里面一定要有一个理念,这个`go generate`是给你用的,不是给使用你这个包的人用的,是方便你来生成一些代码的。 + +这里我们来举一个简单的例子,例如我们经常会使用`yacc`来生成代码,那么我们常用这样的命令: + + go tool yacc -o gopher.go -p parser gopher.y + +-o 指定了输出的文件名, -p指定了package的名称,这是一个单独的命令,如果我们想让`go generate`来触发这个命令,那么就可以在当前目录的任意一个`xxx.go`文件里面的任意位置增加一行如下的注释: + + //go:generate go tool yacc -o gopher.go -p parser gopher.y + +这里我们注意了,`//go:generate`是没有任何空格的,这其实就是一个固定的格式,在扫描源码文件的时候就是根据这个来判断的。 + +所以我们可以通过如下的命令来生成,编译,测试。如果`gopher.y`文件有修改,那么就重新执行`go generate`重新生成文件就好。 + + $ go generate + $ go build + $ go test + + +## godoc + +在Go1.2版本之前还支持`go doc`命令,但是之后全部移到了godoc这个命令下,需要这样安装`go get golang.org/x/tools/cmd/godoc` + + 很多人说go不需要任何的第三方文档,例如chm手册之类的(其实我已经做了一个了,[chm手册](https://github.com/astaxie/godoc)),因为它内部就有一个很强大的文档工具。 + + 如何查看相应package的文档呢? + 例如builtin包,那么执行`godoc builtin` + 如果是http包,那么执行`godoc net/http` + 查看某一个包里面的函数,那么执行`godoc fmt Printf` + 也可以查看相应的代码,执行`godoc -src fmt Printf` + + 通过命令在命令行执行 godoc -http=:端口号 比如`godoc -http=:8080`。然后在浏览器中打开`127.0.0.1:8080`,你将会看到一个golang.org的本地copy版本,通过它你可以查询pkg文档等其它内容。如果你设置了GOPATH,在pkg分类下,不但会列出标准包的文档,还会列出你本地`GOPATH`中所有项目的相关文档,这对于经常被墙的用户来说是一个不错的选择。 + +## 其它命令 + + go还提供了其它很多的工具,例如下面的这些工具 + + go version 查看go当前的版本 + go env 查看当前go的环境变量 + go list 列出当前全部安装的package + go run 编译并运行Go程序 + +以上这些工具还有很多参数没有一一介绍,用户可以使用`go help 命令`获取更详细的帮助信息。 + + +## links + * [目录]() + * 上一节: [GOPATH与工作空间](<01.2.md>) + * 下一节: [Go开发工具](<01.4.md>) diff --git a/zh/01.4.md b/zh/01.4.md index 2b8deabd..8e1e6b38 100644 --- a/zh/01.4.md +++ b/zh/01.4.md @@ -1,636 +1,636 @@ -# 1.4 Go开发工具 - -本节我将介绍几个开发工具,它们都具有自动化提示,自动化fmt功能。因为它们都是跨平台的,所以安装步骤之类的都是通用的。 - -## LiteIDE - - LiteIDE是一款专门为Go语言开发的跨平台轻量级集成开发环境(IDE),由visualfc编写。 - - ![](images/1.4.liteide.png?raw=true) - -图1.4 LiteIDE主界面 - -**LiteIDE主要特点:** - -* 支持主流操作系统 - * Windows - * Linux - * MacOS X -* Go编译环境管理和切换 - * 管理和切换多个Go编译环境 - * 支持Go语言交叉编译 -* 与Go标准一致的项目管理方式 - * 基于GOPATH的包浏览器 - * 基于GOPATH的编译系统 - * 基于GOPATH的Api文档检索 -* Go语言的编辑支持 - * 类浏览器和大纲显示 - * Gocode(代码自动完成工具)的完美支持 - * Go语言文档查看和Api快速检索 - * 代码表达式信息显示`F1` - * 源代码定义跳转支持`F2` - * Gdb断点和调试支持 - * gofmt自动格式化支持 -* 其他特征 - * 支持多国语言界面显示 - * 完全插件体系结构 - * 支持编辑器配色方案 - * 基于Kate的语法显示支持 - * 基于全文的单词自动完成 - * 支持键盘快捷键绑定方案 - * Markdown文档编辑支持 - * 实时预览和同步显示 - * 自定义CSS显示 - * 可导出HTML和PDF文档 - * 批量转换/合并为HTML/PDF文档 - -**LiteIDE安装配置** - -* LiteIDE安装 - * 下载地址 - * 源码地址 - - 首先安装好Go语言环境,然后根据操作系统下载LiteIDE对应的压缩文件直接解压即可使用。 - -* 编译环境设置 - - 根据自身系统要求切换和配置LiteIDE当前使用的环境变量。 - - 以Windows操作系统,64位Go语言为例, - 工具栏的环境配置中选择win64,点`编辑环境`,进入LiteIDE编辑win64.env文件 - - GOROOT=c:\go - GOBIN= - GOARCH=amd64 - GOOS=windows - CGO_ENABLED=1 - - PATH=%GOBIN%;%GOROOT%\bin;%PATH% - 。。。 - - 将其中的`GOROOT=c:\go`修改为当前Go安装路径,存盘即可,如果有MinGW64,可以将`c:\MinGW64\bin`加入PATH中以便go调用gcc支持CGO编译。 - - 以Linux操作系统,64位Go语言为例, - 工具栏的环境配置中选择linux64,点`编辑环境`,进入LiteIDE编辑linux64.env文件 - - GOROOT=$HOME/go - GOBIN= - GOARCH=amd64 - GOOS=linux - CGO_ENABLED=1 - - PATH=$GOBIN:$GOROOT/bin:$PATH - 。。。 - - 将其中的`GOROOT=$HOME/go`修改为当前Go安装路径,存盘即可。 - -* GOPATH设置 - - Go语言的工具链使用GOPATH设置,是Go语言开发的项目路径列表,在命令行中输入(在LiteIDE中也可以`Ctrl+,`直接输入)`go help gopath`快速查看GOPATH文档。 - - 在LiteIDE中可以方便的查看和设置GOPATH。通过`菜单-查看-GOPATH`设置,可以查看系统中已存在的GOPATH列表, - 同时可根据需要添加项目目录到自定义GOPATH列表中。 - -## Sublime Text - - 这里将介绍Sublime Text 3(以下简称Sublime)+ GoSublime + gocode的组合,那么为什么选择这个组合呢? - - - 自动化提示代码,如下图所示 - - ![](images/1.4.sublime1.png?raw=true) - - 图1.5 sublime自动化提示界面 - - - 保存的时候自动格式化代码,让您编写的代码更加美观,符合Go的标准。 - - 支持项目管理 - - ![](images/1.4.sublime2.png?raw=true) - - 图1.6 sublime项目管理界面 - - - 支持语法高亮 - - Sublime Text 3可免费使用,只是保存次数达到一定数量之后就会提示是否购买,点击取消继续用,和正式注册版本没有任何区别。 - - -接下来就开始讲如何安装,下载 [Sublime](http://www.sublimetext.com/) - - 根据自己相应的系统下载相应的版本,然后打开Sublime,对于不熟悉Sublime的同学可以先看一下这篇文章[Sublime Text 全程指南](http://blog.jobbole.com/88648/)或者[sublime text3入门教程](http://blog.csdn.net/sam976/article/details/52076271) - - 1. 打开之后安装 Package Control:Ctrl+` 打开命令行,执行如下代码: - - 适用于 Sublime Text 3: - -```Go -import urllib.request,os;pf='Package Control.sublime-package';ipp=sublime.installed_packages_path();urllib.request.install_opener(urllib.request.build_opener(urllib.request.ProxyHandler()));open(os.path.join(ipp,pf),'wb').write(urllib.request.urlopen('http://sublime.wbond.net/'+pf.replace(' ','%20')).read()) -``` - 适用于 Sublime Text 2: - -```Go -import urllib2,os;pf='Package Control.sublime-package';ipp=sublime.installed_packages_path();os.makedirs(ipp)ifnotos.path.exists(ipp)elseNone;urllib2.install_opener(urllib2.build_opener(urllib2.ProxyHandler()));open(os.path.join(ipp,pf),'wb').write(urllib2.urlopen('http://sublime.wbond.net/'+pf.replace(' ','%20')).read());print('Please restart Sublime Text to finish installation') -``` - - 这个时候重启一下Sublime,可以发现在在菜单栏多了一个如下的栏目,说明Package Control已经安装成功了。 - - ![](images/1.4.sublime3.png?raw=true) - - 图1.7 sublime包管理 - - - 2. 安装完之后就可以安装Sublime的插件了。需安装GoSublime、SidebarEnhancements和Go Build,安装插件之后记得重启Sublime生效,Ctrl+Shift+p打开Package Controll 输入`pcip`(即“Package Control: Install Package”的缩写)。 - - 这个时候看左下角显示正在读取包数据,完成之后出现如下界面 - - ![](images/1.4.sublime4.png?raw=true) - - 图1.8 sublime安装插件界面 - - 这个时候输入GoSublime,按确定就开始安装了。同理应用于SidebarEnhancements和Go Build。 - - 3. 安装 [gocode](https://github.com/nsf/gocode/) - - go get -u github.com/nsf/gocode - - gocode 将会安装在默认`$GOBIN` - - 另外建议安装gotests(生成测试代码): - - - 先在sublime安装gotests插件,再运行: - - -```Go -go get -u -v github.com/cweill/gotests/... -``` - - 3. 验证是否安装成功,你可以打开Sublime,打开main.go,看看语法是不是高亮了,输入`import`是不是自动化提示了,`import "fmt"`之后,输入`fmt.`是不是自动化提示有函数了。 - - 如果已经出现这个提示,那说明你已经安装完成了,并且完成了自动提示。 - - 如果没有出现这样的提示,一般就是你的`$PATH`没有配置正确。你可以打开终端,输入gocode,是不是能够正确运行,如果不行就说明`$PATH`没有配置正确。 - (针对XP)有时候在终端能运行成功,但sublime无提示或者编译解码错误,请安装sublime text3和convert utf8插件试一试 - - 4. MacOS下已经设置了$GOROOT, $GOPATH, $GOBIN,还是没有自动提示怎么办。 - - 请在sublime中使用command + 9, 然后输入env检查$PATH, GOROOT, $GOPATH, $GOBIN等变量, 如果没有请采用下面的方法。 - - 首先建立下面的连接, 然后从Terminal中直接启动sublime - - ln -s /Applications/Sublime\ Text\ 2.app/Contents/SharedSupport/bin/subl /usr/local/bin/sublime - - -## Visual Studio Code - -vscode是微软基于Electron和web技术构建的开源编辑器, 是一款很强大的编辑器。开源地址:https://github.com/Microsoft/vscode - -1、安装Visual Studio Code 最新版 - -官方网站:https://code.visualstudio.com/ -下载Visual Studio Code 最新版,安装过程略。 - -2、安装Go插件 - -点击右边的 Extensions 图标 -搜索Go插件 -在插件列表中,选择 Go,进行安装,安装之后,系统会提示重启 Visual Studio Code。 - -建议把自动保存功能开启。开启方法为:选择菜单 File,点击 Auto save。 - -vscode代码设置可用于Go扩展。这些都可以在用户的喜好来设置或工作区设置(.vscode/settings.json)。 - -打开首选项-用户设置 settings.json: - -```Go - -{ - "go.buildOnSave": true, - "go.lintOnSave": true, - "go.vetOnSave": true, - "go.buildFlags": [], - "go.lintFlags": [], - "go.vetFlags": [], - "go.coverOnSave": false, - "go.useCodeSnippetsOnFunctionSuggest": false, - "go.formatOnSave": true, - //goimports - "go.formatTool": "goreturns", - "go.goroot": "",//你的Goroot - "go.gopath": "",//你的Gopath -} -``` - -接着安装依赖包支持(网络不稳定,请直接到 Github [Golang](https://github.com/golang) 下载再移动到相关目录): -```Go -go get -u -v github.com/nsf/gocode -go get -u -v github.com/rogpeppe/godef -go get -u -v github.com/zmb3/gogetdoc -go get -u -v github.com/golang/lint/golint -go get -u -v github.com/lukehoban/go-outline -go get -u -v sourcegraph.com/sqs/goreturns -go get -u -v golang.org/x/tools/cmd/gorename -go get -u -v github.com/tpng/gopkgs -go get -u -v github.com/newhook/go-symbols -go get -u -v golang.org/x/tools/cmd/guru -go get -u -v github.com/cweill/gotests/... -``` - -vscode 还有一项很强大的功能就是断点调试,结合 [delve](https://github.com/derekparker/delve) 可以很好的进行 Go 代码调试 - -```Go - -go get -v -u github.com/peterh/liner github.com/derekparker/delve/cmd/dlv - -brew install go-delve/delve/delve(mac可选) - -``` -如果有问题再来一遍: -```Go -go get -v -u github.com/peterh/liner github.com/derekparker/delve/cmd/dlv -``` -注意:修改"dlv-cert"证书, 选择"显示简介"->"信任"->"代码签名" 修改为: 始终信任 - -打开首选项-工作区设置,配置launch.json: - -```Go -{ - "version": "0.2.0", - "configurations": [ - { - "name": "main.go", - "type": "go", - "request": "launch", - "mode": "debug", - "remotePath": "", - "port": 2345, - "host": "127.0.0.1", - "program": "${workspaceRoot}",//工作空间路径 - "env": {}, - "args": [], - "showLog": true - } - ] -} -``` - -## Atom - -Atom是Github基于Electron和web技术构建的开源编辑器, 是一款很漂亮强大的编辑器缺点是速度比较慢。 - -首先要先安装下Atom,下载地址: https://atom.io/ - -然后安装go-plus插件: - - go-plus是Atom上面的一款开源的go语言开发环境的的插件 - - 它需要依赖下面的go语言工具: -```Go -1.autocomplete-go :gocode的代码自动提示 -2.gofmt :使用goftm,goimports,goturns -3.builder-go:go-install 和go-test,验证代码,给出建议 -4.gometalinet-linter:goline,vet,gotype的检查 -5.navigator-godef:godef -6.tester-goo :go test -7.gorename :rename - -``` -在Atom中的 Preference 中可以找到install菜单,输入 go-plus,然后点击安装(install) - -就会开始安装 go-plus , go-plus 插件会自动安装对应的依赖插件,如果没有安装对应的go的类库会自动运行: go get 安装。 - - -## GoLand - -GoLand 是 JetBrains 公司推出的 Go 语言集成开发环境,是 Idea Go 插件的强化版。GoLand 同样基于 IntelliJ 平台开发,支持 JetBrains 的插件体系。 - -下载地址: https://www.jetbrains.com/go/ - -## Vim -Vim是从vi发展出来的一个文本编辑器, 代码补全、编译及错误跳转等方便编程的功能特别丰富,在程序员中被广泛使用。 - -vim-go是vim上面的一款开源的go语言使用最为广泛开发环境的的插件 - -插件地址:[github.com/fatih/vim-go](https://github.com/fatih/vim-go) - -vim的插件管理主要有[Pathogen](https://github.com/tpope/vim-pathogen)与[Vundle](https://github.com/VundleVim/Vundle.vim) -,但是其作用的方面不同。 -pathogen是为了解决每一个插件安装后文件分散到多个目录不好管理而存在的。vundle是为了解决自动搜索及下载插件而存在的。 -这两个插件可同时使用。 - -1.安装Vundle - -```sh -mkdir ~/.vim/bundle -git clone https://github.com/gmarik/Vundle.vim.git ~/.vim/bundle/Vundle.vim -``` - -修改.vimrc,将Vundle的相关配置置在最开始处([详细参考Vundle的介绍文档](https://github.com/VundleVim/Vundle.vim)) - -```sh -set nocompatible " be iMproved, required -filetype off " required - -" set the runtime path to include Vundle and initialize -set rtp+=~/.vim/bundle/Vundle.vim -call vundle#begin() - -" let Vundle manage Vundle, required -Plugin 'gmarik/Vundle.vim' - -" All of your Plugins must be added before the following line -call vundle#end() " required -filetype plugin indent on " required - -``` -2.安装Vim-go - -修改~/.vimrc,在vundle#begin和vundle#end间增加一行: - -```sh - -Plugin 'fatih/vim-go' -``` - -在Vim内执行: PluginInstall - -3.安装YCM(Your Complete Me)进行自动补全 -在~/.vimrc中添加一行: -```sh - -Plugin 'Valloric/YouCompleteMe' -``` -在Vim内执行: PluginInstall - - -![](images/1.4.vim.png?raw=true) - -图1.9 VIM编辑器自动化提示Go界面 - -接着我们继续配置vim: - - 1. 配置vim高亮显示 - - cp -r $GOROOT/misc/vim/* ~/.vim/ - - 2. 在~/.vimrc文件中增加语法高亮显示 - - filetype plugin indent on - syntax on - - 3. 安装[Gocode](https://github.com/nsf/gocode/) - - go get -u github.com/nsf/gocode - - gocode默认安装到`$GOPATH/bin`下面。 - - 4. 配置[Gocode](https://github.com/nsf/gocode/) - - ~ cd $GOPATH/src/github.com/nsf/gocode/vim - ~ ./update.bash - ~ gocode set propose-builtins true - propose-builtins true - ~ gocode set lib-path "/home/border/gocode/pkg/linux_amd64" - lib-path "/home/border/gocode/pkg/linux_amd64" - ~ gocode set - propose-builtins true - lib-path "/home/border/gocode/pkg/linux_amd64" - - >gocode set里面的两个参数的含意说明: - > - >propose-builtins:是否自动提示Go的内置函数、类型和常量,默认为false,不提示。 - > - >lib-path:默认情况下,gocode只会搜索**$GOPATH/pkg/$GOOS_$GOARCH** 和 **$GOROOT/pkg/$GOOS_$GOARCH**目录下的包,当然这个设置就是可以设置我们额外的lib能访问的路径 - - - 5. 恭喜你,安装完成,你现在可以使用`:e main.go`体验一下开发Go的乐趣。 - -更多VIM 设定, 可参考[链接](http://www.cnblogs.com/witcxc/archive/2011/12/28/2304704.html) - -## Emacs -Emacs传说中的神器,她不仅仅是一个编辑器,它是一个整合环境,或可称它为集成开发环境,这些功能如让使用者置身于全功能的操作系统中。 - - ![](images/1.4.emacs.png?raw=true) - -图1.10 Emacs编辑Go主界面 - -1. 配置Emacs高亮显示 - - cp $GOROOT/misc/emacs/* ~/.emacs.d/ - -2. 安装[Gocode](https://github.com/nsf/gocode/) - - go get -u github.com/nsf/gocode - - gocode默认安装到`$GOBIN`里面下面。 - -3. 配置[Gocode](https://github.com/nsf/gocode/) - - - ~ cd $GOPATH/src/github.com/nsf/gocode/emacs - ~ cp go-autocomplete.el ~/.emacs.d/ - ~ gocode set propose-builtins true - propose-builtins true - ~ gocode set lib-path "/home/border/gocode/pkg/linux_amd64" // 换为你自己的路径 - lib-path "/home/border/gocode/pkg/linux_amd64" - ~ gocode set - propose-builtins true - lib-path "/home/border/gocode/pkg/linux_amd64" - -4. 需要安装 [Auto Completion](http://www.emacswiki.org/emacs/AutoComplete) - - 下载AutoComplete并解压 - - ~ make install DIR=$HOME/.emacs.d/auto-complete - - 配置~/.emacs文件 - - ;;auto-complete - (require 'auto-complete-config) - (add-to-list 'ac-dictionary-directories "~/.emacs.d/auto-complete/ac-dict") - (ac-config-default) - (local-set-key (kbd "M-/") 'semantic-complete-analyze-inline) - (local-set-key "." 'semantic-complete-self-insert) - (local-set-key ">" 'semantic-complete-self-insert) - - 详细信息参考: http://www.emacswiki.org/emacs/AutoComplete - -5. 配置.emacs - - ;; golang mode - (require 'go-mode-load) - (require 'go-autocomplete) - ;; speedbar - ;; (speedbar 1) - (speedbar-add-supported-extension ".go") - (add-hook - 'go-mode-hook - '(lambda () - ;; gocode - (auto-complete-mode 1) - (setq ac-sources '(ac-source-go)) - ;; Imenu & Speedbar - (setq imenu-generic-expression - '(("type" "^type *\\([^ \t\n\r\f]*\\)" 1) - ("func" "^func *\\(.*\\) {" 1))) - (imenu-add-to-menubar "Index") - ;; Outline mode - (make-local-variable 'outline-regexp) - (setq outline-regexp "//\\.\\|//[^\r\n\f][^\r\n\f]\\|pack\\|func\\|impo\\|cons\\|var.\\|type\\|\t\t*....") - (outline-minor-mode 1) - (local-set-key "\M-a" 'outline-previous-visible-heading) - (local-set-key "\M-e" 'outline-next-visible-heading) - ;; Menu bar - (require 'easymenu) - (defconst go-hooked-menu - '("Go tools" - ["Go run buffer" go t] - ["Go reformat buffer" go-fmt-buffer t] - ["Go check buffer" go-fix-buffer t])) - (easy-menu-define - go-added-menu - (current-local-map) - "Go tools" - go-hooked-menu) - - ;; Other - (setq show-trailing-whitespace t) - )) - ;; helper function - (defun go () - "run current buffer" - (interactive) - (compile (concat "go run " (buffer-file-name)))) - - ;; helper function - (defun go-fmt-buffer () - "run gofmt on current buffer" - (interactive) - (if buffer-read-only - (progn - (ding) - (message "Buffer is read only")) - (let ((p (line-number-at-pos)) - (filename (buffer-file-name)) - (old-max-mini-window-height max-mini-window-height)) - (show-all) - (if (get-buffer "*Go Reformat Errors*") - (progn - (delete-windows-on "*Go Reformat Errors*") - (kill-buffer "*Go Reformat Errors*"))) - (setq max-mini-window-height 1) - (if (= 0 (shell-command-on-region (point-min) (point-max) "gofmt" "*Go Reformat Output*" nil "*Go Reformat Errors*" t)) - (progn - (erase-buffer) - (insert-buffer-substring "*Go Reformat Output*") - (goto-char (point-min)) - (forward-line (1- p))) - (with-current-buffer "*Go Reformat Errors*" - (progn - (goto-char (point-min)) - (while (re-search-forward "" nil t) - (replace-match filename)) - (goto-char (point-min)) - (compilation-mode)))) - (setq max-mini-window-height old-max-mini-window-height) - (delete-windows-on "*Go Reformat Output*") - (kill-buffer "*Go Reformat Output*")))) - ;; helper function - (defun go-fix-buffer () - "run gofix on current buffer" - (interactive) - (show-all) - (shell-command-on-region (point-min) (point-max) "go tool fix -diff")) - -6. 恭喜你,你现在可以体验在神器中开发Go的乐趣。默认speedbar是关闭的,如果打开需要把 ;; (speedbar 1) 前面的注释去掉,或者也可以通过 *M-x speedbar* 手动开启。 - -## Eclipse -Eclipse也是非常常用的开发利器,以下介绍如何使用Eclipse来编写Go程序。 - - ![](images/1.4.eclipse1.png?raw=true) - -图1.11 Eclipse编辑Go的主界面 - -1. 首先下载并安装好[Eclipse](http://www.eclipse.org/) - -2. 下载[goclipse](https://code.google.com/p/goclipse/)插件 - - http://code.google.com/p/goclipse/wiki/InstallationInstructions - -3. 下载gocode,用于go的代码补全提示 - - gocode的github地址: - - https://github.com/nsf/gocode - - 在windows下要安装git,通常用[msysgit](https://code.google.com/p/msysgit/) - - 再在cmd下安装: - - go get -u github.com/nsf/gocode - - 也可以下载代码,直接用go build来编译,会生成gocode.exe - -4. 下载[MinGW](http://sourceforge.net/projects/mingw/files/MinGW/)并按要求装好 - -5. 配置插件 - - Windows->Reference->Go - - (1).配置Go的编译器 - - ![](images/1.4.eclipse2.png?raw=true) - - 图1.12 设置Go的一些基础信息 - - - (2).配置Gocode(可选,代码补全),设置Gocode路径为之前生成的gocode.exe文件 - - ![](images/1.4.eclipse3.png?raw=true) - - 图1.13 设置gocode信息 - - (3).配置GDB(可选,做调试用),设置GDB路径为MingW安装目录下的gdb.exe文件 - - ![](images/1.4.eclipse4.png?raw=true) - - 图1.14 设置GDB信息 - -6. 测试是否成功 - - 新建一个go工程,再建立一个hello.go。如下图: - - ![](images/1.4.eclipse5.png?raw=true) - - 图1.15 新建项目编辑文件 - - 调试如下(要在console中用输入命令来调试): - - ![](images/1.4.eclipse6.png?raw=true) - - 图1.16 调试Go程序 - -## IntelliJ IDEA -熟悉Java的读者应该对于idea不陌生,idea是通过一个插件来支持go语言的高亮语法,代码提示和重构实现。 - -1. 先下载idea,idea支持多平台:win,mac,linux,如果有钱就买个正式版,如果不行就使用社区免费版,对于只是开发Go语言来说免费版足够用了 - - ![](images/1.4.idea1.png?raw=true) - -2. 安装Go插件,点击菜单File中的Setting,找到Plugins,点击,Broswer repo按钮。国内的用户可能会报错,自己解决哈。 - - ![](images/1.4.idea3.png?raw=true) - -3. 这时候会看见很多插件,搜索找到Golang,双击,download and install。等到golang那一行后面出现Downloaded标志后,点OK。 - - ![](images/1.4.idea4.png?raw=true) - - 然后点 Apply .这时候IDE会要求你重启。 - -4. 重启完毕后,创建新项目会发现已经可以创建golang项目了: - - ![](images/1.4.idea5.png?raw=true) - - 下一步,会要求你输入 go sdk的位置,一般都安装在C:\Go,linux和mac根据自己的安装目录设置,选中目录确定,就可以了。 - -## links - * [目录]() - * 上一节: [Go 命令](<01.3.md>) - * 下一节: [总结](<01.5.md>) +# 1.4 Go开发工具 + +本节我将介绍几个开发工具,它们都具有自动化提示,自动化fmt功能。因为它们都是跨平台的,所以安装步骤之类的都是通用的。 + +## LiteIDE + + LiteIDE是一款专门为Go语言开发的跨平台轻量级集成开发环境(IDE),由visualfc编写。 + + ![](images/1.4.liteide.png?raw=true) + +图1.4 LiteIDE主界面 + +**LiteIDE主要特点:** + +* 支持主流操作系统 + * Windows + * Linux + * MacOS X +* Go编译环境管理和切换 + * 管理和切换多个Go编译环境 + * 支持Go语言交叉编译 +* 与Go标准一致的项目管理方式 + * 基于GOPATH的包浏览器 + * 基于GOPATH的编译系统 + * 基于GOPATH的Api文档检索 +* Go语言的编辑支持 + * 类浏览器和大纲显示 + * Gocode(代码自动完成工具)的完美支持 + * Go语言文档查看和Api快速检索 + * 代码表达式信息显示`F1` + * 源代码定义跳转支持`F2` + * Gdb断点和调试支持 + * gofmt自动格式化支持 +* 其他特征 + * 支持多国语言界面显示 + * 完全插件体系结构 + * 支持编辑器配色方案 + * 基于Kate的语法显示支持 + * 基于全文的单词自动完成 + * 支持键盘快捷键绑定方案 + * Markdown文档编辑支持 + * 实时预览和同步显示 + * 自定义CSS显示 + * 可导出HTML和PDF文档 + * 批量转换/合并为HTML/PDF文档 + +**LiteIDE安装配置** + +* LiteIDE安装 + * 下载地址 + * 源码地址 + + 首先安装好Go语言环境,然后根据操作系统下载LiteIDE对应的压缩文件直接解压即可使用。 + +* 编译环境设置 + + 根据自身系统要求切换和配置LiteIDE当前使用的环境变量。 + + 以Windows操作系统,64位Go语言为例, + 工具栏的环境配置中选择win64,点`编辑环境`,进入LiteIDE编辑win64.env文件 + + GOROOT=c:\go + GOBIN= + GOARCH=amd64 + GOOS=windows + CGO_ENABLED=1 + + PATH=%GOBIN%;%GOROOT%\bin;%PATH% + 。。。 + + 将其中的`GOROOT=c:\go`修改为当前Go安装路径,存盘即可,如果有MinGW64,可以将`c:\MinGW64\bin`加入PATH中以便go调用gcc支持CGO编译。 + + 以Linux操作系统,64位Go语言为例, + 工具栏的环境配置中选择linux64,点`编辑环境`,进入LiteIDE编辑linux64.env文件 + + GOROOT=$HOME/go + GOBIN= + GOARCH=amd64 + GOOS=linux + CGO_ENABLED=1 + + PATH=$GOBIN:$GOROOT/bin:$PATH + 。。。 + + 将其中的`GOROOT=$HOME/go`修改为当前Go安装路径,存盘即可。 + +* GOPATH设置 + + Go语言的工具链使用GOPATH设置,是Go语言开发的项目路径列表,在命令行中输入(在LiteIDE中也可以`Ctrl+,`直接输入)`go help gopath`快速查看GOPATH文档。 + + 在LiteIDE中可以方便的查看和设置GOPATH。通过`菜单-查看-GOPATH`设置,可以查看系统中已存在的GOPATH列表, + 同时可根据需要添加项目目录到自定义GOPATH列表中。 + +## Sublime Text + + 这里将介绍Sublime Text 3(以下简称Sublime)+ GoSublime + gocode的组合,那么为什么选择这个组合呢? + + - 自动化提示代码,如下图所示 + + ![](images/1.4.sublime1.png?raw=true) + + 图1.5 sublime自动化提示界面 + + - 保存的时候自动格式化代码,让您编写的代码更加美观,符合Go的标准。 + - 支持项目管理 + + ![](images/1.4.sublime2.png?raw=true) + + 图1.6 sublime项目管理界面 + + - 支持语法高亮 + - Sublime Text 3可免费使用,只是保存次数达到一定数量之后就会提示是否购买,点击取消继续用,和正式注册版本没有任何区别。 + + +接下来就开始讲如何安装,下载 [Sublime](http://www.sublimetext.com/) + + 根据自己相应的系统下载相应的版本,然后打开Sublime,对于不熟悉Sublime的同学可以先看一下这篇文章[Sublime Text 全程指南](http://blog.jobbole.com/88648/)或者[sublime text3入门教程](http://blog.csdn.net/sam976/article/details/52076271) + + 1. 打开之后安装 Package Control:Ctrl+` 打开命令行,执行如下代码: + + 适用于 Sublime Text 3: + +```Go +import urllib.request,os;pf='Package Control.sublime-package';ipp=sublime.installed_packages_path();urllib.request.install_opener(urllib.request.build_opener(urllib.request.ProxyHandler()));open(os.path.join(ipp,pf),'wb').write(urllib.request.urlopen('http://sublime.wbond.net/'+pf.replace(' ','%20')).read()) +``` + 适用于 Sublime Text 2: + +```Go +import urllib2,os;pf='Package Control.sublime-package';ipp=sublime.installed_packages_path();os.makedirs(ipp)ifnotos.path.exists(ipp)elseNone;urllib2.install_opener(urllib2.build_opener(urllib2.ProxyHandler()));open(os.path.join(ipp,pf),'wb').write(urllib2.urlopen('http://sublime.wbond.net/'+pf.replace(' ','%20')).read());print('Please restart Sublime Text to finish installation') +``` + + 这个时候重启一下Sublime,可以发现在在菜单栏多了一个如下的栏目,说明Package Control已经安装成功了。 + + ![](images/1.4.sublime3.png?raw=true) + + 图1.7 sublime包管理 + + + 2. 安装完之后就可以安装Sublime的插件了。需安装GoSublime、SidebarEnhancements和Go Build,安装插件之后记得重启Sublime生效,Ctrl+Shift+p打开Package Controll 输入`pcip`(即“Package Control: Install Package”的缩写)。 + + 这个时候看左下角显示正在读取包数据,完成之后出现如下界面 + + ![](images/1.4.sublime4.png?raw=true) + + 图1.8 sublime安装插件界面 + + 这个时候输入GoSublime,按确定就开始安装了。同理应用于SidebarEnhancements和Go Build。 + + 3. 安装 [gocode](https://github.com/nsf/gocode/) + + go get -u github.com/nsf/gocode + + gocode 将会安装在默认`$GOBIN` + + 另外建议安装gotests(生成测试代码): + + + 先在sublime安装gotests插件,再运行: + + +```Go +go get -u -v github.com/cweill/gotests/... +``` + + 3. 验证是否安装成功,你可以打开Sublime,打开main.go,看看语法是不是高亮了,输入`import`是不是自动化提示了,`import "fmt"`之后,输入`fmt.`是不是自动化提示有函数了。 + + 如果已经出现这个提示,那说明你已经安装完成了,并且完成了自动提示。 + + 如果没有出现这样的提示,一般就是你的`$PATH`没有配置正确。你可以打开终端,输入gocode,是不是能够正确运行,如果不行就说明`$PATH`没有配置正确。 + (针对XP)有时候在终端能运行成功,但sublime无提示或者编译解码错误,请安装sublime text3和convert utf8插件试一试 + + 4. MacOS下已经设置了$GOROOT, $GOPATH, $GOBIN,还是没有自动提示怎么办。 + + 请在sublime中使用command + 9, 然后输入env检查$PATH, GOROOT, $GOPATH, $GOBIN等变量, 如果没有请采用下面的方法。 + + 首先建立下面的连接, 然后从Terminal中直接启动sublime + + ln -s /Applications/Sublime\ Text\ 2.app/Contents/SharedSupport/bin/subl /usr/local/bin/sublime + + +## Visual Studio Code + +vscode是微软基于Electron和web技术构建的开源编辑器, 是一款很强大的编辑器。开源地址:https://github.com/Microsoft/vscode + +1、安装Visual Studio Code 最新版 + +官方网站:https://code.visualstudio.com/ +下载Visual Studio Code 最新版,安装过程略。 + +2、安装Go插件 + +点击右边的 Extensions 图标 +搜索Go插件 +在插件列表中,选择 Go,进行安装,安装之后,系统会提示重启 Visual Studio Code。 + +建议把自动保存功能开启。开启方法为:选择菜单 File,点击 Auto save。 + +vscode代码设置可用于Go扩展。这些都可以在用户的喜好来设置或工作区设置(.vscode/settings.json)。 + +打开首选项-用户设置 settings.json: + +```Go + +{ + "go.buildOnSave": true, + "go.lintOnSave": true, + "go.vetOnSave": true, + "go.buildFlags": [], + "go.lintFlags": [], + "go.vetFlags": [], + "go.coverOnSave": false, + "go.useCodeSnippetsOnFunctionSuggest": false, + "go.formatOnSave": true, + //goimports + "go.formatTool": "goreturns", + "go.goroot": "",//你的Goroot + "go.gopath": "",//你的Gopath +} +``` + +接着安装依赖包支持(网络不稳定,请直接到 GitHub [Golang](https://github.com/golang) 下载再移动到相关目录): +```Go +go get -u -v github.com/nsf/gocode +go get -u -v github.com/rogpeppe/godef +go get -u -v github.com/zmb3/gogetdoc +go get -u -v github.com/golang/lint/golint +go get -u -v github.com/lukehoban/go-outline +go get -u -v sourcegraph.com/sqs/goreturns +go get -u -v golang.org/x/tools/cmd/gorename +go get -u -v github.com/tpng/gopkgs +go get -u -v github.com/newhook/go-symbols +go get -u -v golang.org/x/tools/cmd/guru +go get -u -v github.com/cweill/gotests/... +``` + +vscode 还有一项很强大的功能就是断点调试,结合 [delve](https://github.com/derekparker/delve) 可以很好的进行 Go 代码调试 + +```Go + +go get -v -u github.com/peterh/liner github.com/derekparker/delve/cmd/dlv + +brew install go-delve/delve/delve(mac可选) + +``` +如果有问题再来一遍: +```Go +go get -v -u github.com/peterh/liner github.com/derekparker/delve/cmd/dlv +``` +注意:修改"dlv-cert"证书, 选择"显示简介"->"信任"->"代码签名" 修改为: 始终信任 + +打开首选项-工作区设置,配置launch.json: + +```Go +{ + "version": "0.2.0", + "configurations": [ + { + "name": "main.go", + "type": "go", + "request": "launch", + "mode": "debug", + "remotePath": "", + "port": 2345, + "host": "127.0.0.1", + "program": "${workspaceRoot}",//工作空间路径 + "env": {}, + "args": [], + "showLog": true + } + ] +} +``` + +## Atom + +Atom是GitHub基于Electron和web技术构建的开源编辑器, 是一款很漂亮强大的编辑器缺点是速度比较慢。 + +首先要先安装下Atom,下载地址: https://atom.io/ + +然后安装go-plus插件: + + go-plus是Atom上面的一款开源的go语言开发环境的的插件 + + 它需要依赖下面的go语言工具: +```Go +1.autocomplete-go :gocode的代码自动提示 +2.gofmt :使用goftm,goimports,goturns +3.builder-go:go-install 和go-test,验证代码,给出建议 +4.gometalinet-linter:goline,vet,gotype的检查 +5.navigator-godef:godef +6.tester-goo :go test +7.gorename :rename + +``` +在Atom中的 Preference 中可以找到install菜单,输入 go-plus,然后点击安装(install) + +就会开始安装 go-plus , go-plus 插件会自动安装对应的依赖插件,如果没有安装对应的go的类库会自动运行: go get 安装。 + + +## GoLand + +GoLand 是 JetBrains 公司推出的 Go 语言集成开发环境,是 Idea Go 插件的强化版。GoLand 同样基于 IntelliJ 平台开发,支持 JetBrains 的插件体系。 + +下载地址: https://www.jetbrains.com/go/ + +## Vim +Vim是从vi发展出来的一个文本编辑器, 代码补全、编译及错误跳转等方便编程的功能特别丰富,在程序员中被广泛使用。 + +vim-go是vim上面的一款开源的go语言使用最为广泛开发环境的的插件 + +插件地址:[github.com/fatih/vim-go](https://github.com/fatih/vim-go) + +vim的插件管理主要有[Pathogen](https://github.com/tpope/vim-pathogen)与[Vundle](https://github.com/VundleVim/Vundle.vim) +,但是其作用的方面不同。 +pathogen是为了解决每一个插件安装后文件分散到多个目录不好管理而存在的。vundle是为了解决自动搜索及下载插件而存在的。 +这两个插件可同时使用。 + +1.安装Vundle + +```sh +mkdir ~/.vim/bundle +git clone https://github.com/gmarik/Vundle.vim.git ~/.vim/bundle/Vundle.vim +``` + +修改.vimrc,将Vundle的相关配置置在最开始处([详细参考Vundle的介绍文档](https://github.com/VundleVim/Vundle.vim)) + +```sh +set nocompatible " be iMproved, required +filetype off " required + +" set the runtime path to include Vundle and initialize +set rtp+=~/.vim/bundle/Vundle.vim +call vundle#begin() + +" let Vundle manage Vundle, required +Plugin 'gmarik/Vundle.vim' + +" All of your Plugins must be added before the following line +call vundle#end() " required +filetype plugin indent on " required + +``` +2.安装Vim-go + +修改~/.vimrc,在vundle#begin和vundle#end间增加一行: + +```sh + +Plugin 'fatih/vim-go' +``` + +在Vim内执行: PluginInstall + +3.安装YCM(Your Complete Me)进行自动补全 +在~/.vimrc中添加一行: +```sh + +Plugin 'Valloric/YouCompleteMe' +``` +在Vim内执行: PluginInstall + + +![](images/1.4.vim.png?raw=true) + +图1.9 VIM编辑器自动化提示Go界面 + +接着我们继续配置vim: + + 1. 配置vim高亮显示 + + cp -r $GOROOT/misc/vim/* ~/.vim/ + + 2. 在~/.vimrc文件中增加语法高亮显示 + + filetype plugin indent on + syntax on + + 3. 安装[Gocode](https://github.com/nsf/gocode/) + + go get -u github.com/nsf/gocode + + gocode默认安装到`$GOPATH/bin`下面。 + + 4. 配置[Gocode](https://github.com/nsf/gocode/) + + ~ cd $GOPATH/src/github.com/nsf/gocode/vim + ~ ./update.bash + ~ gocode set propose-builtins true + propose-builtins true + ~ gocode set lib-path "/home/border/gocode/pkg/linux_amd64" + lib-path "/home/border/gocode/pkg/linux_amd64" + ~ gocode set + propose-builtins true + lib-path "/home/border/gocode/pkg/linux_amd64" + + >gocode set里面的两个参数的含意说明: + > + >propose-builtins:是否自动提示Go的内置函数、类型和常量,默认为false,不提示。 + > + >lib-path:默认情况下,gocode只会搜索**$GOPATH/pkg/$GOOS_$GOARCH** 和 **$GOROOT/pkg/$GOOS_$GOARCH**目录下的包,当然这个设置就是可以设置我们额外的lib能访问的路径 + + + 5. 恭喜你,安装完成,你现在可以使用`:e main.go`体验一下开发Go的乐趣。 + +更多VIM 设定, 可参考[链接](http://www.cnblogs.com/witcxc/archive/2011/12/28/2304704.html) + +## Emacs +Emacs传说中的神器,她不仅仅是一个编辑器,它是一个整合环境,或可称它为集成开发环境,这些功能如让使用者置身于全功能的操作系统中。 + + ![](images/1.4.emacs.png?raw=true) + +图1.10 Emacs编辑Go主界面 + +1. 配置Emacs高亮显示 + + cp $GOROOT/misc/emacs/* ~/.emacs.d/ + +2. 安装[Gocode](https://github.com/nsf/gocode/) + + go get -u github.com/nsf/gocode + + gocode默认安装到`$GOBIN`里面下面。 + +3. 配置[Gocode](https://github.com/nsf/gocode/) + + + ~ cd $GOPATH/src/github.com/nsf/gocode/emacs + ~ cp go-autocomplete.el ~/.emacs.d/ + ~ gocode set propose-builtins true + propose-builtins true + ~ gocode set lib-path "/home/border/gocode/pkg/linux_amd64" // 换为你自己的路径 + lib-path "/home/border/gocode/pkg/linux_amd64" + ~ gocode set + propose-builtins true + lib-path "/home/border/gocode/pkg/linux_amd64" + +4. 需要安装 [Auto Completion](http://www.emacswiki.org/emacs/AutoComplete) + + 下载AutoComplete并解压 + + ~ make install DIR=$HOME/.emacs.d/auto-complete + + 配置~/.emacs文件 + + ;;auto-complete + (require 'auto-complete-config) + (add-to-list 'ac-dictionary-directories "~/.emacs.d/auto-complete/ac-dict") + (ac-config-default) + (local-set-key (kbd "M-/") 'semantic-complete-analyze-inline) + (local-set-key "." 'semantic-complete-self-insert) + (local-set-key ">" 'semantic-complete-self-insert) + + 详细信息参考: http://www.emacswiki.org/emacs/AutoComplete + +5. 配置.emacs + + ;; golang mode + (require 'go-mode-load) + (require 'go-autocomplete) + ;; speedbar + ;; (speedbar 1) + (speedbar-add-supported-extension ".go") + (add-hook + 'go-mode-hook + '(lambda () + ;; gocode + (auto-complete-mode 1) + (setq ac-sources '(ac-source-go)) + ;; Imenu & Speedbar + (setq imenu-generic-expression + '(("type" "^type *\\([^ \t\n\r\f]*\\)" 1) + ("func" "^func *\\(.*\\) {" 1))) + (imenu-add-to-menubar "Index") + ;; Outline mode + (make-local-variable 'outline-regexp) + (setq outline-regexp "//\\.\\|//[^\r\n\f][^\r\n\f]\\|pack\\|func\\|impo\\|cons\\|var.\\|type\\|\t\t*....") + (outline-minor-mode 1) + (local-set-key "\M-a" 'outline-previous-visible-heading) + (local-set-key "\M-e" 'outline-next-visible-heading) + ;; Menu bar + (require 'easymenu) + (defconst go-hooked-menu + '("Go tools" + ["Go run buffer" go t] + ["Go reformat buffer" go-fmt-buffer t] + ["Go check buffer" go-fix-buffer t])) + (easy-menu-define + go-added-menu + (current-local-map) + "Go tools" + go-hooked-menu) + + ;; Other + (setq show-trailing-whitespace t) + )) + ;; helper function + (defun go () + "run current buffer" + (interactive) + (compile (concat "go run " (buffer-file-name)))) + + ;; helper function + (defun go-fmt-buffer () + "run gofmt on current buffer" + (interactive) + (if buffer-read-only + (progn + (ding) + (message "Buffer is read only")) + (let ((p (line-number-at-pos)) + (filename (buffer-file-name)) + (old-max-mini-window-height max-mini-window-height)) + (show-all) + (if (get-buffer "*Go Reformat Errors*") + (progn + (delete-windows-on "*Go Reformat Errors*") + (kill-buffer "*Go Reformat Errors*"))) + (setq max-mini-window-height 1) + (if (= 0 (shell-command-on-region (point-min) (point-max) "gofmt" "*Go Reformat Output*" nil "*Go Reformat Errors*" t)) + (progn + (erase-buffer) + (insert-buffer-substring "*Go Reformat Output*") + (goto-char (point-min)) + (forward-line (1- p))) + (with-current-buffer "*Go Reformat Errors*" + (progn + (goto-char (point-min)) + (while (re-search-forward "" nil t) + (replace-match filename)) + (goto-char (point-min)) + (compilation-mode)))) + (setq max-mini-window-height old-max-mini-window-height) + (delete-windows-on "*Go Reformat Output*") + (kill-buffer "*Go Reformat Output*")))) + ;; helper function + (defun go-fix-buffer () + "run gofix on current buffer" + (interactive) + (show-all) + (shell-command-on-region (point-min) (point-max) "go tool fix -diff")) + +6. 恭喜你,你现在可以体验在神器中开发Go的乐趣。默认speedbar是关闭的,如果打开需要把 ;; (speedbar 1) 前面的注释去掉,或者也可以通过 *M-x speedbar* 手动开启。 + +## Eclipse +Eclipse也是非常常用的开发利器,以下介绍如何使用Eclipse来编写Go程序。 + + ![](images/1.4.eclipse1.png?raw=true) + +图1.11 Eclipse编辑Go的主界面 + +1. 首先下载并安装好[Eclipse](http://www.eclipse.org/) + +2. 下载[goclipse](https://code.google.com/p/goclipse/)插件 + + http://code.google.com/p/goclipse/wiki/InstallationInstructions + +3. 下载gocode,用于go的代码补全提示 + + gocode的GitHub地址: + + https://github.com/nsf/gocode + + 在windows下要安装git,通常用[msysgit](https://code.google.com/p/msysgit/) + + 再在cmd下安装: + + go get -u github.com/nsf/gocode + + 也可以下载代码,直接用go build来编译,会生成gocode.exe + +4. 下载[MinGW](http://sourceforge.net/projects/mingw/files/MinGW/)并按要求装好 + +5. 配置插件 + + Windows->Reference->Go + + (1).配置Go的编译器 + + ![](images/1.4.eclipse2.png?raw=true) + + 图1.12 设置Go的一些基础信息 + + + (2).配置Gocode(可选,代码补全),设置Gocode路径为之前生成的gocode.exe文件 + + ![](images/1.4.eclipse3.png?raw=true) + + 图1.13 设置gocode信息 + + (3).配置GDB(可选,做调试用),设置GDB路径为MingW安装目录下的gdb.exe文件 + + ![](images/1.4.eclipse4.png?raw=true) + + 图1.14 设置GDB信息 + +6. 测试是否成功 + + 新建一个go工程,再建立一个hello.go。如下图: + + ![](images/1.4.eclipse5.png?raw=true) + + 图1.15 新建项目编辑文件 + + 调试如下(要在console中用输入命令来调试): + + ![](images/1.4.eclipse6.png?raw=true) + + 图1.16 调试Go程序 + +## IntelliJ IDEA +熟悉Java的读者应该对于idea不陌生,idea是通过一个插件来支持go语言的高亮语法,代码提示和重构实现。 + +1. 先下载idea,idea支持多平台:win,mac,linux,如果有钱就买个正式版,如果不行就使用社区免费版,对于只是开发Go语言来说免费版足够用了 + + ![](images/1.4.idea1.png?raw=true) + +2. 安装Go插件,点击菜单File中的Setting,找到Plugins,点击,Broswer repo按钮。国内的用户可能会报错,自己解决哈。 + + ![](images/1.4.idea3.png?raw=true) + +3. 这时候会看见很多插件,搜索找到Golang,双击,download and install。等到golang那一行后面出现Downloaded标志后,点OK。 + + ![](images/1.4.idea4.png?raw=true) + + 然后点 Apply .这时候IDE会要求你重启。 + +4. 重启完毕后,创建新项目会发现已经可以创建golang项目了: + + ![](images/1.4.idea5.png?raw=true) + + 下一步,会要求你输入 go sdk的位置,一般都安装在C:\Go,linux和mac根据自己的安装目录设置,选中目录确定,就可以了。 + +## links + * [目录]() + * 上一节: [Go 命令](<01.3.md>) + * 下一节: [总结](<01.5.md>) diff --git a/zh/05.4.md b/zh/05.4.md index 21babbaa..7db0ab5b 100644 --- a/zh/05.4.md +++ b/zh/05.4.md @@ -13,7 +13,7 @@ Go实现的支持PostgreSQL的驱动也很多,因为国外很多人在开发 - https://github.com/jbarham/gopgsqldriver 支持database/sql驱动,纯Go写的 - https://github.com/lxn/go-pgsql 支持database/sql驱动,纯Go写的 -在下面的示例中我采用了第一个驱动,因为它目前使用的人最多,在github上也比较活跃。 +在下面的示例中我采用了第一个驱动,因为它目前使用的人最多,在GitHub上也比较活跃。 ## 实例代码 数据库建表语句: diff --git a/zh/13.6.md b/zh/13.6.md index 209b3f29..a2a250c5 100644 --- a/zh/13.6.md +++ b/zh/13.6.md @@ -1,7 +1,7 @@ -# 13.6 小结 -这一章我们主要介绍了如何实现一个基础的Go语言框架,框架包含有路由设计,由于Go内置的http包中路由的一些不足点,我们设计了动态路由规则,然后介绍了MVC模式中的Controller设计,controller实现了REST的实现,这个主要思路来源于tornado框架,然后设计实现了模板的layout以及自动化渲染等技术,主要采用了Go内置的模板引擎,最后我们介绍了一些辅助的日志、配置等信息的设计,通过这些设计我们实现了一个基础的框架beego,目前该框架已经开源在github,最后我们通过beego实现了一个博客系统,通过实例代码详细的展现了如何快速的开发一个站点。 - -## links - * [目录]() - * 上一章: [实现博客的增删改](<13.5.md>) - * 下一节: [扩展Web框架](<14.0.md>) \ No newline at end of file +# 13.6 小结 +这一章我们主要介绍了如何实现一个基础的Go语言框架,框架包含有路由设计,由于Go内置的http包中路由的一些不足点,我们设计了动态路由规则,然后介绍了MVC模式中的Controller设计,controller实现了REST的实现,这个主要思路来源于tornado框架,然后设计实现了模板的layout以及自动化渲染等技术,主要采用了Go内置的模板引擎,最后我们介绍了一些辅助的日志、配置等信息的设计,通过这些设计我们实现了一个基础的框架beego,目前该框架已经开源在GitHub,最后我们通过beego实现了一个博客系统,通过实例代码详细的展现了如何快速的开发一个站点。 + +## links + * [目录]() + * 上一章: [实现博客的增删改](<13.5.md>) + * 下一节: [扩展Web框架](<14.0.md>) diff --git a/zh/14.4.md b/zh/14.4.md index baf7d1da..64f36395 100644 --- a/zh/14.4.md +++ b/zh/14.4.md @@ -1,265 +1,265 @@ -# 14.4 用户认证 -在开发Web应用过程中,用户认证是开发者经常遇到的问题,用户登录、注册、登出等操作,而一般认证也分为三个方面的认证 - -- HTTP Basic和 HTTP Digest认证 -- 第三方集成认证:QQ、微博、豆瓣、OPENID、google、github、facebook和twitter等 -- 自定义的用户登录、注册、登出,一般都是基于session、cookie认证 - -beego目前没有针对这三种方式进行任何形式的集成,但是可以充分的利用第三方开源库来实现上面的三种方式的用户认证,不过后续beego会对前面两种认证逐步集成。 - -## HTTP Basic和 HTTP Digest认证 -这两个认证是一些应用采用的比较简单的认证,目前已经有开源的第三方库支持这两个认证: -```Go - -github.com/abbot/go-http-auth -``` -下面代码演示了如何把这个库引入beego中从而实现认证: -```Go - -package controllers - -import ( - "github.com/abbot/go-http-auth" - "github.com/astaxie/beego" -) - -func Secret(user, realm string) string { - if user == "john" { - // password is "hello" - return "$1$dlPL2MqE$oQmn16q49SqdmhenQuNgs1" - } - return "" -} - -type MainController struct { - beego.Controller -} - -func (this *MainController) Prepare() { - a := auth.NewBasicAuthenticator("example.com", Secret) - if username := a.CheckAuth(this.Ctx.Request); username == "" { - a.RequireAuth(this.Ctx.ResponseWriter, this.Ctx.Request) - } -} - -func (this *MainController) Get() { - this.Data["Username"] = "astaxie" - this.Data["Email"] = "astaxie@gmail.com" - this.TplNames = "index.tpl" -} -``` -上面代码利用了beego的prepare函数,在执行正常逻辑之前调用了认证函数,这样就非常简单的实现了http auth,digest的认证也是同样的原理。 - -## oauth和oauth2的认证 -oauth和oauth2是目前比较流行的两种认证方式,还好第三方有一个库实现了这个认证,但是是国外实现的,并没有QQ、微博之类的国内应用认证集成: -```Go - -github.com/bradrydzewski/go.auth -``` -下面代码演示了如何把该库引入beego中从而实现oauth的认证,这里以github为例演示: - -1. 添加两条路由 -```Go - -beego.RegisterController("/auth/login", &controllers.GithubController{}) -beego.RegisterController("/mainpage", &controllers.PageController{}) -``` -2. 然后我们处理GithubController登陆的页面: -```Go -package controllers - -import ( - "github.com/astaxie/beego" - "github.com/bradrydzewski/go.auth" -) - -const ( - githubClientKey = "a0864ea791ce7e7bd0df" - githubSecretKey = "a0ec09a647a688a64a28f6190b5a0d2705df56ca" -) - -type GithubController struct { - beego.Controller -} - -func (this *GithubController) Get() { - // set the auth parameters - auth.Config.CookieSecret = []byte("7H9xiimk2QdTdYI7rDddfJeV") - auth.Config.LoginSuccessRedirect = "/mainpage" - auth.Config.CookieSecure = false - - githubHandler := auth.Github(githubClientKey, githubSecretKey) - - githubHandler.ServeHTTP(this.Ctx.ResponseWriter, this.Ctx.Request) -} - -``` -3. 处理登陆成功之后的页面 -```Go -package controllers - -import ( - "github.com/astaxie/beego" - "github.com/bradrydzewski/go.auth" - "net/http" - "net/url" -) - -type PageController struct { - beego.Controller -} - -func (this *PageController) Get() { - // set the auth parameters - auth.Config.CookieSecret = []byte("7H9xiimk2QdTdYI7rDddfJeV") - auth.Config.LoginSuccessRedirect = "/mainpage" - auth.Config.CookieSecure = false - - user, err := auth.GetUserCookie(this.Ctx.Request) - - //if no active user session then authorize user - if err != nil || user.Id() == "" { - http.Redirect(this.Ctx.ResponseWriter, this.Ctx.Request, auth.Config.LoginRedirect, http.StatusSeeOther) - return - } - - //else, add the user to the URL and continue - this.Ctx.Request.URL.User = url.User(user.Id()) - this.Data["pic"] = user.Picture() - this.Data["id"] = user.Id() - this.Data["name"] = user.Name() - this.TplNames = "home.tpl" -} - -``` -整个的流程如下,首先打开浏览器输入地址: - -![](images/14.4.github.png?raw=true) - -图14.4 显示带有登录按钮的首页 - -然后点击链接出现如下界面: - -![](images/14.4.github2.png?raw=true) - -图14.5 点击登录按钮后显示github的授权页 - -然后点击Authorize app就出现如下界面: - -![](images/14.4.github3.png?raw=true) - -图14.6 授权登录之后显示的获取到的github信息页 - -## 自定义认证 -自定义的认证一般都是和session结合验证的,如下代码来源于一个基于beego的开源博客: -```Go - -//登陆处理 -func (this *LoginController) Post() { - this.TplNames = "login.tpl" - this.Ctx.Request.ParseForm() - username := this.Ctx.Request.Form.Get("username") - password := this.Ctx.Request.Form.Get("password") - md5Password := md5.New() - io.WriteString(md5Password, password) - buffer := bytes.NewBuffer(nil) - fmt.Fprintf(buffer, "%x", md5Password.Sum(nil)) - newPass := buffer.String() - - now := time.Now().Format("2006-01-02 15:04:05") - - userInfo := models.GetUserInfo(username) - if userInfo.Password == newPass { - var users models.User - users.Last_logintime = now - models.UpdateUserInfo(users) - - //登录成功设置session - sess := globalSessions.SessionStart(this.Ctx.ResponseWriter, this.Ctx.Request) - sess.Set("uid", userInfo.Id) - sess.Set("uname", userInfo.Username) - - this.Ctx.Redirect(302, "/") - } -} - -//注册处理 -func (this *RegController) Post() { - this.TplNames = "reg.tpl" - this.Ctx.Request.ParseForm() - username := this.Ctx.Request.Form.Get("username") - password := this.Ctx.Request.Form.Get("password") - usererr := checkUsername(username) - fmt.Println(usererr) - if usererr == false { - this.Data["UsernameErr"] = "Username error, Please to again" - return - } - - passerr := checkPassword(password) - if passerr == false { - this.Data["PasswordErr"] = "Password error, Please to again" - return - } - - md5Password := md5.New() - io.WriteString(md5Password, password) - buffer := bytes.NewBuffer(nil) - fmt.Fprintf(buffer, "%x", md5Password.Sum(nil)) - newPass := buffer.String() - - now := time.Now().Format("2006-01-02 15:04:05") - - userInfo := models.GetUserInfo(username) - - if userInfo.Username == "" { - var users models.User - users.Username = username - users.Password = newPass - users.Created = now - users.Last_logintime = now - models.AddUser(users) - - //登录成功设置session - sess := globalSessions.SessionStart(this.Ctx.ResponseWriter, this.Ctx.Request) - sess.Set("uid", userInfo.Id) - sess.Set("uname", userInfo.Username) - this.Ctx.Redirect(302, "/") - } else { - this.Data["UsernameErr"] = "User already exists" - } - -} - -func checkPassword(password string) (b bool) { - if ok, _ := regexp.MatchString("^[a-zA-Z0-9]{4,16}$", password); !ok { - return false - } - return true -} - -func checkUsername(username string) (b bool) { - if ok, _ := regexp.MatchString("^[a-zA-Z0-9]{4,16}$", username); !ok { - return false - } - return true -} -``` -有了用户登陆和注册之后,其他模块的地方可以增加如下这样的用户是否登陆的判断: -```Go - -func (this *AddBlogController) Prepare() { - sess := globalSessions.SessionStart(this.Ctx.ResponseWriter, this.Ctx.Request) - sess_uid := sess.Get("userid") - sess_username := sess.Get("username") - if sess_uid == nil { - this.Ctx.Redirect(302, "/admin/login") - return - } - this.Data["Username"] = sess_username -} -``` -## links - * [目录]() - * 上一节: [表单及验证支持](<14.3.md>) - * 下一节: [多语言支持](<14.5.md>) \ No newline at end of file +# 14.4 用户认证 +在开发Web应用过程中,用户认证是开发者经常遇到的问题,用户登录、注册、登出等操作,而一般认证也分为三个方面的认证 + +- HTTP Basic和 HTTP Digest认证 +- 第三方集成认证:QQ、微博、豆瓣、OPENID、google、GitHub、facebook和twitter等 +- 自定义的用户登录、注册、登出,一般都是基于session、cookie认证 + +beego目前没有针对这三种方式进行任何形式的集成,但是可以充分的利用第三方开源库来实现上面的三种方式的用户认证,不过后续beego会对前面两种认证逐步集成。 + +## HTTP Basic和 HTTP Digest认证 +这两个认证是一些应用采用的比较简单的认证,目前已经有开源的第三方库支持这两个认证: +```Go + +github.com/abbot/go-http-auth +``` +下面代码演示了如何把这个库引入beego中从而实现认证: +```Go + +package controllers + +import ( + "github.com/abbot/go-http-auth" + "github.com/astaxie/beego" +) + +func Secret(user, realm string) string { + if user == "john" { + // password is "hello" + return "$1$dlPL2MqE$oQmn16q49SqdmhenQuNgs1" + } + return "" +} + +type MainController struct { + beego.Controller +} + +func (this *MainController) Prepare() { + a := auth.NewBasicAuthenticator("example.com", Secret) + if username := a.CheckAuth(this.Ctx.Request); username == "" { + a.RequireAuth(this.Ctx.ResponseWriter, this.Ctx.Request) + } +} + +func (this *MainController) Get() { + this.Data["Username"] = "astaxie" + this.Data["Email"] = "astaxie@gmail.com" + this.TplNames = "index.tpl" +} +``` +上面代码利用了beego的prepare函数,在执行正常逻辑之前调用了认证函数,这样就非常简单的实现了http auth,digest的认证也是同样的原理。 + +## oauth和oauth2的认证 +oauth和oauth2是目前比较流行的两种认证方式,还好第三方有一个库实现了这个认证,但是是国外实现的,并没有QQ、微博之类的国内应用认证集成: +```Go + +github.com/bradrydzewski/go.auth +``` +下面代码演示了如何把该库引入beego中从而实现oauth的认证,这里以GitHub为例演示: + +1. 添加两条路由 +```Go + +beego.RegisterController("/auth/login", &controllers.GithubController{}) +beego.RegisterController("/mainpage", &controllers.PageController{}) +``` +2. 然后我们处理GithubController登陆的页面: +```Go +package controllers + +import ( + "github.com/astaxie/beego" + "github.com/bradrydzewski/go.auth" +) + +const ( + githubClientKey = "a0864ea791ce7e7bd0df" + githubSecretKey = "a0ec09a647a688a64a28f6190b5a0d2705df56ca" +) + +type GithubController struct { + beego.Controller +} + +func (this *GithubController) Get() { + // set the auth parameters + auth.Config.CookieSecret = []byte("7H9xiimk2QdTdYI7rDddfJeV") + auth.Config.LoginSuccessRedirect = "/mainpage" + auth.Config.CookieSecure = false + + githubHandler := auth.Github(githubClientKey, githubSecretKey) + + githubHandler.ServeHTTP(this.Ctx.ResponseWriter, this.Ctx.Request) +} + +``` +3. 处理登陆成功之后的页面 +```Go +package controllers + +import ( + "github.com/astaxie/beego" + "github.com/bradrydzewski/go.auth" + "net/http" + "net/url" +) + +type PageController struct { + beego.Controller +} + +func (this *PageController) Get() { + // set the auth parameters + auth.Config.CookieSecret = []byte("7H9xiimk2QdTdYI7rDddfJeV") + auth.Config.LoginSuccessRedirect = "/mainpage" + auth.Config.CookieSecure = false + + user, err := auth.GetUserCookie(this.Ctx.Request) + + //if no active user session then authorize user + if err != nil || user.Id() == "" { + http.Redirect(this.Ctx.ResponseWriter, this.Ctx.Request, auth.Config.LoginRedirect, http.StatusSeeOther) + return + } + + //else, add the user to the URL and continue + this.Ctx.Request.URL.User = url.User(user.Id()) + this.Data["pic"] = user.Picture() + this.Data["id"] = user.Id() + this.Data["name"] = user.Name() + this.TplNames = "home.tpl" +} + +``` +整个的流程如下,首先打开浏览器输入地址: + +![](images/14.4.github.png?raw=true) + +图14.4 显示带有登录按钮的首页 + +然后点击链接出现如下界面: + +![](images/14.4.github2.png?raw=true) + +图14.5 点击登录按钮后显示GitHub的授权页 + +然后点击Authorize app就出现如下界面: + +![](images/14.4.github3.png?raw=true) + +图14.6 授权登录之后显示的获取到的GitHub信息页 + +## 自定义认证 +自定义的认证一般都是和session结合验证的,如下代码来源于一个基于beego的开源博客: +```Go + +//登陆处理 +func (this *LoginController) Post() { + this.TplNames = "login.tpl" + this.Ctx.Request.ParseForm() + username := this.Ctx.Request.Form.Get("username") + password := this.Ctx.Request.Form.Get("password") + md5Password := md5.New() + io.WriteString(md5Password, password) + buffer := bytes.NewBuffer(nil) + fmt.Fprintf(buffer, "%x", md5Password.Sum(nil)) + newPass := buffer.String() + + now := time.Now().Format("2006-01-02 15:04:05") + + userInfo := models.GetUserInfo(username) + if userInfo.Password == newPass { + var users models.User + users.Last_logintime = now + models.UpdateUserInfo(users) + + //登录成功设置session + sess := globalSessions.SessionStart(this.Ctx.ResponseWriter, this.Ctx.Request) + sess.Set("uid", userInfo.Id) + sess.Set("uname", userInfo.Username) + + this.Ctx.Redirect(302, "/") + } +} + +//注册处理 +func (this *RegController) Post() { + this.TplNames = "reg.tpl" + this.Ctx.Request.ParseForm() + username := this.Ctx.Request.Form.Get("username") + password := this.Ctx.Request.Form.Get("password") + usererr := checkUsername(username) + fmt.Println(usererr) + if usererr == false { + this.Data["UsernameErr"] = "Username error, Please to again" + return + } + + passerr := checkPassword(password) + if passerr == false { + this.Data["PasswordErr"] = "Password error, Please to again" + return + } + + md5Password := md5.New() + io.WriteString(md5Password, password) + buffer := bytes.NewBuffer(nil) + fmt.Fprintf(buffer, "%x", md5Password.Sum(nil)) + newPass := buffer.String() + + now := time.Now().Format("2006-01-02 15:04:05") + + userInfo := models.GetUserInfo(username) + + if userInfo.Username == "" { + var users models.User + users.Username = username + users.Password = newPass + users.Created = now + users.Last_logintime = now + models.AddUser(users) + + //登录成功设置session + sess := globalSessions.SessionStart(this.Ctx.ResponseWriter, this.Ctx.Request) + sess.Set("uid", userInfo.Id) + sess.Set("uname", userInfo.Username) + this.Ctx.Redirect(302, "/") + } else { + this.Data["UsernameErr"] = "User already exists" + } + +} + +func checkPassword(password string) (b bool) { + if ok, _ := regexp.MatchString("^[a-zA-Z0-9]{4,16}$", password); !ok { + return false + } + return true +} + +func checkUsername(username string) (b bool) { + if ok, _ := regexp.MatchString("^[a-zA-Z0-9]{4,16}$", username); !ok { + return false + } + return true +} +``` +有了用户登陆和注册之后,其他模块的地方可以增加如下这样的用户是否登陆的判断: +```Go + +func (this *AddBlogController) Prepare() { + sess := globalSessions.SessionStart(this.Ctx.ResponseWriter, this.Ctx.Request) + sess_uid := sess.Get("userid") + sess_username := sess.Get("username") + if sess_uid == nil { + this.Ctx.Redirect(302, "/admin/login") + return + } + this.Data["Username"] = sess_username +} +``` +## links + * [目录]() + * 上一节: [表单及验证支持](<14.3.md>) + * 下一节: [多语言支持](<14.5.md>) diff --git a/zh/build_new.go b/zh/build_new.go index a11f375a..b3e04c11 100644 --- a/zh/build_new.go +++ b/zh/build_new.go @@ -11,7 +11,7 @@ import ( "strings" ) -// 开发者 github token +// 开发者 GitHub token const token = "" // 定义一个访问者结构体