diff --git a/LANGS.md b/LANGS.md new file mode 100644 index 00000000..a665d0db --- /dev/null +++ b/LANGS.md @@ -0,0 +1,3 @@ +* [English](en/) +* [中文](zh/) +* [日本語](ja/) \ No newline at end of file diff --git a/README.md b/README.md index 584d46ec..28b046bd 100644 --- a/README.md +++ b/README.md @@ -1,35 +1,20 @@ -# 《Go Web 编程》 -这本书目前有多个版本: +# Mulit Language Version +* [English](en/) +* [中文](zh/) +* [日本語](ja/) -[中文开始阅读]() +# Donate -[日文开始阅读]() - -[English Version]() - -目前这本书已经出版,如果你觉得内容还可以,你可以通过下面几个途径购买,谢谢支持: - -- [chinapub](http://product.china-pub.com/3767290) -- [当当网](http://product.dangdang.com/product.aspx?product_id=23231404) -- [京东](http://book.jd.com/11224644.html) -- [Amazon](http://www.amazon.cn/Go-Web%E7%BC%96%E7%A8%8B-%E8%B0%A2%E5%AD%9F%E5%86%9B/dp/B00CHWVAHQ/ref=sr_1_1?s=books&ie=UTF8&qid=1369323453&sr=1-1) - -![](ebook/images/ebook.jpg) - -# 通过捐款支持本书 -如果你喜欢这本《Go Web编程》的话, 可以通过捐款的方式, 支持作者继续更新本书或者做出其他更多好玩好用的开源应用: 比如为本书修补漏洞、添加更多有趣的章节, 或者发行有更多更棒内容的下一版,或者改善beego等等。 - -支付宝扫描捐款: ![](ebook/images/alipay.png) +AliPay: alipay English Donate:[donate](http://beego.me/donate) -## 交流 -欢迎大家加入QQ群:259316004 《Go Web编程》专用交流群 +## Community +QQ群:386056972 -论坛交流:[http://bbs.go-china.org/](http://bbs.go-china.org/) +BBS:[http://golanghome.com/](http://golanghome.com/) -## 致谢 -首先要感谢Golang-China的QQ群102319854(已满),请加2群(384414723),里面的每一个人都很热心,同时要特别感谢几个人 +## Acknowledgments - [四月份平民](https://plus.google.com/110445767383269817959) (review代码) - [Hong Ruiqi](https://github.com/hongruiqi) (review代码) @@ -39,11 +24,9 @@ English Donate:[donate](http://beego.me/donate) - [polaris](https://github.com/polaris1119)(review书) - [雨痕](https://github.com/qyuhen)(review第二章) -## 授权许可 -除特别声明外,本书中的内容使用[CC BY-SA 3.0 License](http://creativecommons.org/licenses/by-sa/3.0/)(创作共用 署名-相同方式共享3.0许可协议)授权,代码遵循[BSD 3-Clause License]()(3项条款的BSD许可协议)。 +## License +Book License: [CC BY-SA 3.0 License](http://creativecommons.org/licenses/by-sa/3.0/) -## 开始阅读 -[开始阅读]() +Code License: [BSD 3-Clause License]() -[![githalytics.com alpha](https://cruel-carlota.pagodabox.com/44c98c9d398b8319b6e87edcd3e34144 "githalytics.com")](http://githalytics.com/astaxie/build-web-application-with-golang) diff --git a/ebook/images/ebook.jpg b/cover.jpg similarity index 100% rename from ebook/images/ebook.jpg rename to cover.jpg diff --git a/images b/images deleted file mode 120000 index e0bc9c2a..00000000 --- a/images +++ /dev/null @@ -1 +0,0 @@ -ebook/images/ \ No newline at end of file diff --git a/ja/ebook/01.0.md b/ja/01.0.md similarity index 100% rename from ja/ebook/01.0.md rename to ja/01.0.md diff --git a/ja/ebook/01.1.md b/ja/01.1.md similarity index 84% rename from ja/ebook/01.1.md rename to ja/01.1.md index a290fc4a..ef12dda2 100644 --- a/ja/ebook/01.1.md +++ b/ja/01.1.md @@ -96,13 +96,16 @@ PATHを設定します。`export PATH=$PATH:$GO_INSTALL_DIR/go/bin` もしgoのUsage情報が現れた場合は、goはすでにインストールされています。もしこのコマンドが存在しないと出てきた場合は、自分のPATH環境変数の中にgoのインストールディレクトリが含まれているか確認してください。 -### Windows インストール +### Windows インストール ### -[ダウンロードURL][downlink]に接続し、32bitシステムはgo1.0.3.windows-386.msiをダウンロードします。64bitシステムであればgo1.0.3.windows-amd64.msiをダウンロードします。ファイルをダブルクリックして、デフォルトのまま「次へ」をクリックします。この時goはすでにあなたのシステムにインストールされています。デフォルトでインストール後の環境変数には`c:/go/bin`が追加されています。cmdを開いて、`go`と入力します。 +[Google Code ダウンロードページ][downlink]に接続し、32bit の場合は名前に windows-386 を含む msi パッケージをダウンロードします。64bit であれば名前に windows-amd64 を含むものをダウンロードします。ダウンロード後実行しますが、デフォルトのインストールフォルダである C:\Go\を変更してはいけません。他の場所にインストールしてしまうと、あなたが書いた Go コードが実行できなくなってしまうかもしれません。インストールが終わるとデフォルトで環境変数 Path に Go のインストールフォルダの下にある bin フォルダ `C:\Go\bin\` が追加され、Go のインストールフォルダである `C:\Go\` の値が環境変数 GOROOT に追加されます。 -macインストール成功の画像で、インストールが成功します。 +** インストールが成功しているか確認する ** + +「ファイル名を指定して実行」に `cmd` を入力することでコマンドラインツールを開きます。プロンプトで`go`と入力することで Usage 情報が確認できるか確かめることができます。`cd %GOROOT%` を入力すると、Go のインストールフォルダに入れるか確認できます。どちらも成功していれば、インストールに成功しています。 + +インストールに成功していなければ、環境変数 Path と GOROOT の値を確認してください。もし存在しなければアンインストールの上再インストールし、存在していればコンピュータを再起動し、上の手順を再度お試しください。 -もしGoのUsage情報が現れたら、Goはすでにインストールされています。もしこのコマンドが存在しないと出た場合は自分のPATH環境変数にGoのインストールディレクトリが含まれるか確認してください。 ## サードパーティツールのインストール ### GVM diff --git a/ja/ebook/01.2.md b/ja/01.2.md similarity index 100% rename from ja/ebook/01.2.md rename to ja/01.2.md diff --git a/ja/ebook/01.3.md b/ja/01.3.md similarity index 98% rename from ja/ebook/01.3.md rename to ja/01.3.md index 454a5ece..f2be5d30 100644 --- a/ja/ebook/01.3.md +++ b/ja/01.3.md @@ -33,7 +33,7 @@ array_windows.go array_freebsd.go - `go build`の際、システム名の末尾のファイルから選択的にコンパイルすることができます(linux、darwin、windows、freebsd) + `go build`の際、システム名の末尾のファイルから選択的にコンパイルすることができます(Linux、Darwin、Windows、Freebsd) ## go clean diff --git a/ja/ebook/01.4.md b/ja/01.4.md similarity index 95% rename from ja/ebook/01.4.md rename to ja/01.4.md index a6fd7f8f..04f2123f 100644 --- a/ja/ebook/01.4.md +++ b/ja/01.4.md @@ -166,7 +166,7 @@ "env": { "GOPATH": "$HOME/golang:$GS_GOPATH" } } - `$GS_GOPATH` は gosublime の仮想的な環境変数です。自動的に`.go`ファイルが存在する `~/go/src` を探し出すことで、 `~/go/` をプロジェクトのパスと推測し、自動的に `GOPATH` を適用します。 + `$GS_GOPATH` は gosublime の仮想的な環境変数です。自動的に`.go`ファイルが存在する `~/go/src` を探し出すことで、 `~/go/` をプロジェクトのパスと推測し、自動的に `GOPATH` を適用します。(注意:このような方法ではsublimeにおいてオリジナルのGOPATHを上書きしてしまいます。もしこの設定でエラーが発生した場合は、GOPATHに関連した問題が発生していることになります) もうひとつは、sublime プロジェクトの保存です。 project_name.sublime-project を修正して項目を追加します @@ -226,7 +226,7 @@ Vimはviから発展したテキストエディタです。コード補完、コ 5. おめでとうございます。インストール完了です。あなたは今から`:e main.go`でGoで開発する面白さを体験することができます。 -より多くのVIM 設定は、[リンク](http://monnand.me/p/vim-golang-environment/zhCN/)をご参照ください。 +より多くのVIMの設定は、[リンク](http://monnand.me/p/vim-golang-environment/zhCN/)をご参照ください。 ## Emacs Emacsは伝説の神器です。彼女はエディタであるだけでなく、統合環境でもあります。または開発環境の集大成と呼んでもよいかもしれません。これらの機能はユーザの身を万能のオペレーティングシステムに置きます。 @@ -457,4 +457,4 @@ Javaに親しい読者はideaには不慣れだと思います、ideaはプラ ## links * [目次]() * 前へ: [Goのコマンド](<01.3.md>) - * 次へ: [概要](<01.5.md>) + * 次へ: [まとめ](<01.5.md>) diff --git a/ja/ebook/01.5.md b/ja/01.5.md similarity index 98% rename from ja/ebook/01.5.md rename to ja/01.5.md index 55a7e43a..efd6f52e 100644 --- a/ja/ebook/01.5.md +++ b/ja/01.5.md @@ -1,4 +1,4 @@ -# 1.5 概要 +# 1.5 まとめ この章では主にどのようにしてGoをインストールするかについてご紹介しました。Goは3つの種類のインストール方法があります:ソースコードインストール、標準パッケージインストール、サードパーティツールによるインストールです。インストール後開発環境を整え、ローカルの`$GOPATH`を設定します。`$GOPATH`設定を通じて読者はプロジェクトを作成することができます。次にどのようにプロジェクトをコンパイルするのか説明しました。アプリケーションのインストールといった問題はたくさんのGoコマンドを使用する必要があります。そのため、Goで日常的に用いられるコマンドツールについてもご説明しました。コンパイル、インストール、整形、テストなどのコマンドです。最後にGoの開発ツールについてご紹介しました。現在多くのGoの開発ツールには:LiteIDE、sublime、VIM、Emacs、Eclipse、Ideaといったツールがあります。読者は自分が一番慣れ親しんだツールを設定することができます。便利なツールで素早くGoアプリケーションを開発できるよう願っています。 diff --git a/ja/ebook/02.0.md b/ja/02.0.md similarity index 94% rename from ja/ebook/02.0.md rename to ja/02.0.md index 0a101f13..a2877e37 100644 --- a/ja/ebook/02.0.md +++ b/ja/02.0.md @@ -15,5 +15,5 @@ GoはCに似たコンパイラ型言語です。ですが、このコンパイ ## links * [目次]() - * 前へ: [第一章概要](<01.5.md>) + * 前へ: [第一章まとめ](<01.5.md>) * 次へ: [こんにちは、Go](<02.1.md>) diff --git a/ja/ebook/02.1.md b/ja/02.1.md similarity index 100% rename from ja/ebook/02.1.md rename to ja/02.1.md diff --git a/ja/ebook/02.2.md b/ja/02.2.md similarity index 96% rename from ja/ebook/02.2.md rename to ja/02.2.md index 4d26c2ec..77ef58f1 100644 --- a/ja/ebook/02.2.md +++ b/ja/02.2.md @@ -103,7 +103,7 @@ Goではbool値の型は`bool`です。値は`true`もしくは`false`です。 >注意しなければならないのは、これらの型の変数間は相互に代入または操作を行うことができないということです。コンパイル時にコンパイラはエラーを発生させます。 > ->下のコードはエラーが発生します。 +>下のコードはエラーが発生します。:invalid operation: a + b (mismatched types int8 and int32) > >> var a int8 @@ -135,7 +135,7 @@ Goではbool値の型は`bool`です。値は`true`もしくは`false`です。 frenchHello = "Bonjour" // 通常の代入 } -Goの文字列は変更することができません。例えば下のコードはコンパイル時にエラーが発生します。 +Goの文字列は変更することができません。例えば下のコードはコンパイル時にエラーが発生します。:cannot assign to s[0] var s string = "hello" s[0] = 'c' @@ -168,7 +168,10 @@ Goでは`+`演算子を使って文字列を連結することができます: m := `hello world` -`` ` `` で括られた文字列はRaw文字列です。すなわち、文字列はコード内の形式がそのままプリント時の形式になります。文字列の変更はありません。改行はそのまま出力されます。 +`` ` `` で括られた文字列はRaw文字列です。すなわち、文字列はコード内の形式がそのままプリント時の形式になります。文字列の変更はありません。改行はそのまま出力されます。例えばこの例では以下のように出力されます: + + hello + world ### エラー型 Goにはビルトインの`error`型があります。専らエラー情報の処理に使用されます。Goの`package`の中にはエラー処理を行う`errors`というパッケージがあります。 @@ -383,7 +386,7 @@ sliceには便利な操作があります 下のコードをご覧ください。`map`の読み込みと代入は`slice`と似ています。`key`を通して操作します。ただ、`slice`の`index`は`int`型のみになります。`map`には多くの型があります。`int`でもかまいませんし、`string`や`==`と`!=`演算子が定義されている全ての型でもかまいません。 // keyを文字列で宣言します。値はintとなるディクショナリです。この方法は使用される前にmakeで初期化される必要があります。 - var numbers map[string] int + var numbers map[string]int // もうひとつのmapの宣言方法 numbers := make(map[string]int) numbers["one"] = 1 //代入 @@ -407,7 +410,7 @@ mapを使う段階で注意しなければならないことがいくつかあ `delete`で`map`の要素を削除します: // ディクショナリを初期化します。 - rating := map[string]float32 {"C":5, "Go":4.5, "Python":4.5, "C++":2 } + rating := map[string]float32{"C":5, "Go":4.5, "Python":4.5, "C++":2 } // mapは2つの戻り値があります。2つ目の戻り値では、もしkeyが存在しなければ、okはfalseに、存在すればokはtrueになります。 csharpRating, ok := rating["C#"] if ok { @@ -445,7 +448,7 @@ mapを使う段階で注意しなければならないことがいくつかあ 図2.5 makeとnewの低レイヤでのメモリの割り当て -"ゼロ値"というのは何もカラの値ではありません。これは一種の"変数が埋めらる前"のデフォルト値であり、通常は0です。 +"ゼロ値"というのは何も空の値ではありません。これは一種の"変数が埋めらる前"のデフォルト値であり、通常は0です。 それぞれの型のゼロ値は以下の通りです int 0 diff --git a/ja/ebook/02.3.md b/ja/02.3.md similarity index 95% rename from ja/ebook/02.3.md rename to ja/02.3.md index fa747ac6..def7dedc 100644 --- a/ja/ebook/02.3.md +++ b/ja/02.3.md @@ -1,7 +1,7 @@ # 2.3 フローと関数 この節ではGoの中のフロー制御と関数操作についてご紹介します。 ## フロー制御 -フロー制御はプログラム言語の中の最も偉大な発明です。なぜならこれがあるだけで、あなたはとても簡単なフローの記述でとても複雑なロジックを表現できるからです。フロー制御は3つの部分から成ります:条件判断、ループ制御及び無条件ジャンプです。 +フロー制御はプログラム言語の中の最も偉大な発明です。なぜならこれがあるだけで、あなたはとても簡単なフローの記述でとても複雑なロジックを表現できるからです。Goではフロー制御は3つの部分から成ります:条件判断、ループ制御及び無条件ジャンプです。 ### if `if`はあらゆるプログラミング言語の中で最もよく見かけるものかもしれません。この文法は大雑把に言えば:もし条件を満足しなければ何々を行い、そうでなければまたもう一つ別のことをやるということです。 @@ -50,7 +50,7 @@ Goには`goto`句があります- - ぜひ賢く使ってください。`goto` >タグの名前は大文字小文字を区別します。 ### for -Goにで最も協力なロジックコントロールといえば、`for`です。これはループでデータを読むのに使えます。`while`でロジックをコントロールしても構いません。イテレーション操作も行えます。文法は以下の通りです: +Goにで最も強力なロジックコントロールといえば、`for`です。これはループでデータを読むのに使えます。`while`でロジックをコントロールしても構いません。イテレーション操作も行えます。文法は以下の通りです: for expression1; expression2; expression3 { //... @@ -369,7 +369,7 @@ Goでは関数も変数の一種です。`type`を通して定義します。こ type typeName func(input1 inputType1 , input2 inputType2 [, ...]) (result1 resultType1 [, ...]) -関すを型として扱うことにメリットはあるのでしょうか?ではこの型の関数を値として渡してみましょう。以下の例をご覧ください。 +関数を型として扱うことにメリットはあるのでしょうか?ではこの型の関数を値として渡してみましょう。以下の例をご覧ください。 package main import "fmt" @@ -415,7 +415,7 @@ Goでは関数も変数の一種です。`type`を通して定義します。こ ### PanicとRecover -GoにはJavaのような例外処理はありません。例外を投げないのです。その代わり、`panic`と`recover`を使用します。ぜひ覚えておいてください、これは最後の手段として使うことを。つまり、あなたのコードにあってはなりません。もしくは`panic`を極力減らしてください。これは非常に協力なツールです。賢く使ってください。では、どのように使うのでしょうか? +GoにはJavaのような例外処理はありません。例外を投げないのです。その代わり、`panic`と`recover`を使用します。ぜひ覚えておいてください、これは最後の手段として使うことを。つまり、あなたのコードにあってはなりません。もしくは`panic`を極力減らしてください。これは非常に強力なツールです。賢く使ってください。では、どのように使うのでしょうか? Panic >ビルトイン関数です。オリジナルの処理フローを中断させることができます。パニックが発生するフローの中に入って関数`F`が`panic`をコールします。このプロセスは継続して実行されます。一旦`panic`の`goroutine`が発生すると、コールされた関数がすべて返ります。この時プログラムを抜けます。パニックは直接`panic`をコールします。実行時にエラーを発生させてもかまいません。例えば配列の境界を超えてアクセスする、などです。 @@ -468,7 +468,7 @@ Goのコードを書いている時は、importコマンドによってパッケ fmt.Println("hello world") -上のfmtはGo言語の標準ライブラリです。実はgorootの下にこのモジュールが加えられています。当然Goのインポートは以下のような2つの方法で自分の書いたモジュールを追加することができます: +上のfmtはGo言語の標準ライブラリです。実は`GOROOT`環境変数で指定されたディレクトリの下にこのモジュールが加えられています。当然Goのインポートは以下のような2つの方法で自分の書いたモジュールを追加することができます: 1. 相対パス diff --git a/ja/ebook/02.4.md b/ja/02.4.md similarity index 100% rename from ja/ebook/02.4.md rename to ja/02.4.md diff --git a/ja/ebook/02.5.md b/ja/02.5.md similarity index 85% rename from ja/ebook/02.5.md rename to ja/02.5.md index 4c792663..41f2e3ea 100644 --- a/ja/ebook/02.5.md +++ b/ja/02.5.md @@ -2,7 +2,7 @@ 前の2つの章で関数とstructをご紹介しました。関数をstructのフィールドとして処理したくなったんじゃないですか?今日は関数のもう一つの形態についてご説明します。受け取り手のいる関数で、我々が`method`とよんでいるものです。 ## method -今、このような状況にいると仮定します。あなたは長方形というstructを定義してこの面積を求めようとしています。では、我々の一般的な思考回路に基づけば下のような方法で実現するでしょう。 +今、このような状況にいると仮定します。あなたは長方形というstructを定義してこの面積を求めようとしています。我々の一般的な思考回路に基づけば下のような方法で実現するでしょう。 package main import "fmt" @@ -22,11 +22,11 @@ fmt.Println("Area of r2 is: ", area(r2)) } -このコードは長方形の面積を求めることができますが、area()はRectangleのメソッドで実現されたものではありません(オブジェクト指向のメソッドのようなもの)。Rectangleのオブジェクト(ここではr1,r2)を引数に面積を京s何する関数に渡しているだけです。 +このコードは長方形の面積を求めることができますが、area()はRectangleの(一般的なオブジェクト指向でいうような)メソッドで実現されたものではありません。Rectangleのオブジェクト(ここではr1,r2)を引数に面積を計算する関数に渡しているだけです。 このように実現してももちろん構わないのですが、図形が増えてきて、正方形、五角形ついには多角形になってきた頃、これらの面積も求めようとするとどうでしょう?この場合関数を増やすしかなくなってしまいます。関数名はそれぞれ用意しなければなりません。`area_rectangle, area_circle, area_triangle...`といった具合に。 -下の図で示すように、楕円が関数を表しています。これらの関数はstructに属していない(またはオブジェクト指向の専門用語でclassに属していないといいます)ので、structの外側に単独で存在しており、概念上どのstructにも属していないことになります。 +下の図で示すように、楕円が関数を表しています。これらの関数はstructに属していない(オブジェクト指向用語で言い換えるとclassに属していない)ので、structの外側に単独で存在しており、概念上どのstructにも属していないことになります。 ![](images/2.5.rect_func_without_receiver.png?raw=true) @@ -34,7 +34,7 @@ 明らかにこのような実現方法はエレガントではありません。それに概念からしても"面積"は"形状"の一属性です。これはある特定の形状に属しています。長方形の縦と横と同じようなものです。 -このような理由から`method`の概念が生まれました。`method`はある型の上に付属しています。この文法と関数の宣言の文法はほとんど同じです。ただ、`fenc`の後にreceiver(methodがくっついているということです。)を追加します。 +このような理由から`method`の概念が生まれました。`method`はある型に属しています。この文法と関数の宣言の文法はほとんど同じです。ただ、`func`の後にreceiver(methodがくっついているということです)を追加します。 上で述べた形状の例からすると、method `area()` はある形状(たとえばRectangle)に由来して発生しています。Rectangle.area()の主語はRectangle、area()はRectangleに属するメソッドで外側の関数ではありません。 @@ -89,9 +89,9 @@ methodの文法は以下のとおりです: methodを使う時にはいくつか注意が必要です。 -- methodは名前はまったく同じといってもレシーバが異なればmethodも異なります。 +- methodはまったく同じ名前でもレシーバが異なればmethodも異なります。 - methodはレシーバのフィールドにアクセスすることができます。 -- methodのコールは`.`を通じてアクセスします。structがフィールドにアクセスするのと同じです。 +- methodの呼び出しは`.`を通じて行います。structがフィールドにアクセスするのと同じです。 図解: @@ -122,7 +122,7 @@ methodはstructの上でしか使用されないのでしょうか?当然違 "December":31, } -わかりましたか?簡単でしょう?このように自分のコードの中に意味のある型を定義することができるのです。実際はエイリアスを定義しているだけです。Cのtypedefににたようなもので、例えば上のagesはintの代わりになっています。 +わかりましたか?簡単でしょう?このように自分のコードの中に意味のある型を定義することができるのです。実際はエイリアスを定義しているだけです。Cのtypedefに似たようなもので、例えば上のagesはintの代わりになっています。 それじゃあ、`method`にもどりましょう。 @@ -156,7 +156,7 @@ methodはstructの上でしか使用されないのでしょうか?当然違 b.color = c } - func (bl BoxList) BiggestsColor() Color { + func (bl BoxList) BiggestColor() Color { v := 0.00 k := Color(WHITE) for _, b := range bl { @@ -192,13 +192,13 @@ methodはstructの上でしか使用されないのでしょうか?当然違 fmt.Printf("We have %d boxes in our set\n", len(boxes)) fmt.Println("The volume of the first one is", boxes[0].Volume(), "cm³") fmt.Println("The color of the last one is",boxes[len(boxes)-1].color.String()) - fmt.Println("The biggest one is", boxes.BiggestsColor().String()) + fmt.Println("The biggest one is", boxes.BiggestColor().String()) fmt.Println("Let's paint them all black") boxes.PaintItBlack() fmt.Println("The color of the second one is", boxes[1].color.String()) - fmt.Println("Obviously, now, the biggest one is", boxes.BiggestsColor().String()) + fmt.Println("Obviously, now, the biggest one is", boxes.BiggestColor().String()) } 上のコードはconstでいくつかの定数を定義しています。その後カスタム定義型を定義しています。 @@ -209,20 +209,20 @@ methodはstructの上でしか使用されないのでしょうか?当然違 次に上のカスタム定義型をレシーバとしてmethodを定義します。 -- Volume()はレシーバをBoxとして定義します。Boxの堆積を返します。 +- Volume()はレシーバをBoxとして定義します。Boxの体積を返します。 - SetColor(c Color)はBoxの色をcに変更します。 -- BiggestsColor()はBoxListに定義されており、listの中の体積が最大の色を返します。 -- PointItBlack()はBoxListのすべてのBoxの色を全部黒に変更します。 -- String()はColorに定義されており、Colorno具体的な色を返します(文字列形式) +- BiggestColor()はBoxListに定義されており、listの中の体積が最大の色を返します。 +- PaintItBlack()はBoxListのすべてのBoxの色を全部黒に変更します。 +- String()はColorに定義されており、Colorの具体的な色を返します(文字列形式) 上のコードは文字で書くと非常に簡単に思えませんか?私達は問題を解決する場合問題の描写を通して、対応するコードを書くことで実現します。 ### ポインタとしてのreceiver ではここで、SetColorのメソッドを見なおしてみましょう。このreceiverはBoxのポインタをさしています。そうです。*Boxを使えるのです。どうしてBox本体ではなくポインタを使うのでしょうか? -SetColorを定義した本当の目的はこのBoxの色を変更することです。もしBoxのポインタを渡さなければ、SetCororが受け取るのは実はBoxのコピーになってしまいます。つまり、メソッド内で色の変更を行うと、Boxのコピーを操作しているだけで、本当のBoxではないのです。そのため、ポインタを渡す必要があります。 +SetColorを定義した本当の目的はこのBoxの色を変更することです。もしBoxのポインタを渡さなければ、SetColorが受け取るのは実はBoxのコピーになってしまいます。つまり、メソッド内で色の変更を行うと、Boxのコピーを操作しているだけで、本当のBoxではないのです。そのため、ポインタを渡す必要があります。 -ここではreceiverをメソッドの第一引数にました。こうすれば前の関数で説明した値渡しと参照渡しも難しくなくなるでしょう。 +ここではreceiverをメソッドの第一引数にしました。こうすれば前の関数で説明した値渡しと参照渡しも難しくなくなるでしょう。 もしかしたらSetColor関数の中で以下のように定義すべきじゃないかと思われたかもしれません。`*b.Color=c`、ところが`b.Color=c`でよいのです。ポインタに対応する値を読み込むことが必要ですから。 diff --git a/ja/ebook/02.6.md b/ja/02.6.md similarity index 95% rename from ja/ebook/02.6.md rename to ja/02.6.md index 7c66f9fb..367c9f28 100644 --- a/ja/ebook/02.6.md +++ b/ja/02.6.md @@ -142,7 +142,7 @@ mは3つの型を持つことのできるオブジェクトなので、Men型 mike := Student{Human{"Mike", 25, "222-222-XXX"}, "MIT", 0.00} paul := Student{Human{"Paul", 26, "111-222-XXX"}, "Harvard", 100} sam := Employee{Human{"Sam", 36, "444-222-XXX"}, "Golang Inc.", 1000} - Tom := Employee{Human{"Sam", 36, "444-222-XXX"}, "Things Ltd.", 5000} + Tom := Employee{Human{"Tom", 37, "222-444-XXX"}, "Things Ltd.", 5000} //Men型の変数iを定義します。 var i Men @@ -354,7 +354,7 @@ sort.Interfaceは実は組み込みフィールドです。sort.Interfaceのす } ### リフレクション -Goはリフレクションを実装しています。いわゆるリフレクションとは動的な実行時の状態です。私達が一般的に使用しているパッケージはreflectパッケージです。どのようにreflectパッケージを使うかはオフィシャルのドキュメントに詳細な原理が説明されています。[laws of reflection](http://golang.org/doc/articles/laws_of_reflection.html) +Goはリフレクションを実装しています。リフレクションはプログラムの実行時の状態を検査することができます。私達が一般的に使用しているパッケージはreflectパッケージです。どのようにreflectパッケージを使うかはオフィシャルのドキュメントに詳細な原理が説明されています。[laws of reflection](http://golang.org/doc/articles/laws_of_reflection.html) reflectを使うには3つのステップに分けられます。下で簡単にご説明します:リフレクションは型の値(これらの値はすべて空のインターフェースを実装しています。)。まずこれをreflectオブジェクトに変換する必要があります(reflect.Typeまたはreflect.Valueです。異なる状況によって異なる関数をコールします。)この2つを取得する方法は: diff --git a/ja/ebook/02.7.md b/ja/02.7.md similarity index 95% rename from ja/ebook/02.7.md rename to ja/02.7.md index eb972463..3abf4e5f 100644 --- a/ja/ebook/02.7.md +++ b/ja/02.7.md @@ -31,16 +31,16 @@ goroutineはGoのruntime管理を利用したスレッドコントローラで say("hello") //現在のGoroutines実行 } - 出力: - hello - world - hello - world - hello - world - hello - world - hello + // 上のプログラムを実行すると以下のように出力されます: + // hello + // world + // hello + // world + // hello + // world + // hello + // world + // hello goキーワードで非常に簡単にマルチスレッドプログラミングを実現することがお分かりいただけるかと思います。 上の複数のgoroutineは同じプロセスで実行されています。メモリのデータを共有しますが、デザイン上共有を利用して通信を行ったりせず、通信によって共有を行うようにしましょう。 @@ -137,7 +137,7 @@ channelは`<-`演算子を使ってデータを送ったり受けたりします } } -`for i := range c`でこのchannelがクローズを明示されるまで連続してchannelの中のデータを読み込むことができます。上のコードでchannelのクローズが明示されているのが確認できるかと思います。生産者はキーワード`close`関数によってchannelを閉じます。channelを閉じた後はいかなるデータも送信することはできません。消費側は`v, ok := <-ch`という式でchannelがすでに閉じられているかテストすることができます。もしokにfalseが返ってきたら、channelはすでにどのようなデータも無く、閉じられているということになります。 +`for i := range c`でこのchannelがクローズを明示されるまで連続してchannelの中のデータを読み込むことができます。上のコードでchannelのクローズが明示されているのが確認できるかと思います。生産者は`close`ビルトイン関数によってchannelを閉じます。channelを閉じた後はいかなるデータも送信することはできません。消費側は`v, ok := <-ch`という式でchannelがすでに閉じられているかテストすることができます。もしokにfalseが返ってきたら、channelはすでにどのようなデータも無く、閉じられているということになります。 >生産者の方でchannelが閉じられる事に注意してください。消費側ではありません。これは容易にpanicを引き起こします。 @@ -236,4 +236,4 @@ runtimeパッケージにはgoroutineを処理するいくつかの関数が含 ## links * [目次]() * 前へ: [interface](<02.6.md>) - * 次へ: [概要](<02.8.md>) + * 次へ: [まとめ](<02.8.md>) diff --git a/ja/ebook/02.8.md b/ja/02.8.md similarity index 97% rename from ja/ebook/02.8.md rename to ja/02.8.md index aa48a728..e0b4f8dc 100644 --- a/ja/ebook/02.8.md +++ b/ja/02.8.md @@ -1,4 +1,4 @@ -# 2.8 概要 +# 2.8 まとめ この章では主にGo言語のいくつかの文法をご紹介しました。文法を通してGoがいかに簡単かご覧いただけたかと思います。たった25個のキーワードです。もう一度これらキーワードが何に使われるのか見てみることにしましょう。 diff --git a/ja/ebook/03.0.md b/ja/03.0.md similarity index 81% rename from ja/ebook/03.0.md rename to ja/03.0.md index bf0afd5b..4a0c6538 100644 --- a/ja/ebook/03.0.md +++ b/ja/03.0.md @@ -1,11 +1,11 @@ # 3 Webの基礎 -Webのプログラミングの基礎を勉強することはあなたにとってまさにこの本を読む理由でしょう。事実、どのようにGoを使ってWebアプリケーションをプログラムするかはこの本の目的でもあります。前回までで、Goは既に成熟したHttp処理パッケージを持つことをご紹介しました。これによってどのような事情の動的なWebプログラミングも簡単に作成できます。これ以降の章でご紹介する内容はどれもWebプログラミングの範疇です。この章ではWebに関する概念とGo言語がいかにWebプログラムを実行するかに集中して討論します。 +Webのプログラミングの基礎を勉強することはあなたにとってまさにこの本を読む理由でしょう。事実、どのようにGoを使ってWebアプリケーションをプログラムするかはこの本の目的でもあります。前回までで、Goは既に成熟したHTTP処理パッケージを持つことをご紹介しました。これによってどのような事情の動的なWebプログラミングも簡単に作成できます。これ以降の章でご紹介する内容はどれもWebプログラミングの範疇です。この章ではWebに関する概念とGo言語がいかにWebプログラムを実行するかに集中して討論します。 ## 目次 ![](images/navi3.png?raw=true) ## links * [目次]() - * 前へ: [第二章概要](<02.8.md>) - * 次へ: [webでの作業方法](<03.1.md>) + * 前へ: [第二章まとめ](<02.8.md>) + * 次へ: [Webでの作業方法](<03.1.md>) diff --git a/ja/ebook/03.1.md b/ja/03.1.md similarity index 96% rename from ja/ebook/03.1.md rename to ja/03.1.md index 6d4c9b68..e4eac116 100644 --- a/ja/ebook/03.1.md +++ b/ja/03.1.md @@ -85,6 +85,8 @@ HTTPプロトコルはステートレスです。同じクライアントの前 //空行、リクエストヘッダとボディを分けるために使われます。 //ボディ、リソースへのリクエストのオプション、例えばPOSTが渡すオプション +HTTPプロトコルはサーバに対して交互にリクエストを送る方法が定義されています。基本は四種類。GET,POST,PUT,DELETEです。ひとつのURLアドレスはひとつのネットワーク上のリソースを描写しています。またHTTPの中のGET, POST, PUT, DELETEはこのリソースの検索、修正、増加、削除の4つの操作に対応しています。よく見かけるのはGETとPOSTです。GETは一般的にリソースの情報を取得/検索するために用いられ、POSTはリソース情報を更新するために用いられます。 + fiddlerパケットキャプチャを通して下のようなリクエスト情報を見ることができます。 ![](images/3.1.http.png?raw=true) @@ -95,13 +97,12 @@ fiddlerパケットキャプチャを通して下のようなリクエスト情 図3.5 fiddlerがキャプチャしたPOST情報 -**GETリクエストのボディが空であることがわかります。POSTリクエストにはボディがあります**。 - -HTTPプロトコルはサーバに対して交互にリクエストを送る方法が定義されています。基本は四種類。GET,POST,PUT,DELETEです。ひとつのURLアドレスはひとつのネットワーク上のリソースを描写しています。またHTTPの中のGET, POST, PUT, DELETEはこのリソースの検索、修正、増加、削除の4つの操作に対応しています。よく見かけるのはGETとPOSTです。GETは一般的にリソースの情報を取得/検索するために用いられ、POSTはリソース情報を更新するために用いられます。 GETとPOSTの区別を見てみましょう。 -1. GETが入力するデータはURLの後に置かれます。?によってURLと渡すデータを分割します。オプションの間は&で繋ぎます。例えばEditPosts.aspx?name=test1&id=12345。POSTメソッドは入力するデータをHTTPパケットのBodyの中に置きます。 -2. GETが入力するデータの大きさには制限があります。(ブラウザのURLに対する長に制限があるためです。)またPOSTメソッドで入力するデータには制限がありません。 -3. GETメソッドで入力されたデータはセキュリティの問題を引き起こします。例えばログイン画面があったとして、GETメソッドでデータを入力した場合、ユーザ名とパスワードはURL上にあらわれてしまうことになります。もしページがバッファリングされていたり他の人によっがこのマシンにアクセスすることができれば、ヒストリログからこのユーザのアカウントとパスワードを取得することができてしまいます。 + +1. GETリクエストのボディが空であることがわかります。POSTリクエストにはボディがあります。 +2. GETが入力するデータはURLの後に置かれます。?によってURLと渡すデータを分割します。オプションの間は&で繋ぎます。例えばEditPosts.aspx?name=test1&id=12345。POSTメソッドは入力するデータをHTTPパケットのBodyの中に置きます。 +3. GETが入力するデータの大きさには制限があります。(ブラウザのURLに対する長に制限があるためです。)またPOSTメソッドで入力するデータには制限がありません。 +4. GETメソッドで入力されたデータはセキュリティの問題を引き起こします。例えばログイン画面があったとして、GETメソッドでデータを入力した場合、ユーザ名とパスワードはURL上にあらわれてしまうことになります。もしページがバッファリングされていたり他の人によっがこのマシンにアクセスすることができれば、ヒストリログからこのユーザのアカウントとパスワードを取得することができてしまいます。 ### HTTPレスポンスパケット(サーバ情報) HTTPのresponseパケットを見てみることにしましょう。構造は以下のとおりです: @@ -116,7 +117,7 @@ HTTPのresponseパケットを見てみることにしましょう。構造は //空行 ヘッダとボディを分けるために使われます。 ) * 前へ: [Webの基礎](<03.0.md>) - * 次へ: [GOでwebサーバを建てる](<03.2.md>) + * 次へ: [GOでWebサーバを建てる](<03.2.md>) diff --git a/ja/ebook/03.2.md b/ja/03.2.md similarity index 80% rename from ja/ebook/03.2.md rename to ja/03.2.md index a8e8565c..71f4a502 100644 --- a/ja/ebook/03.2.md +++ b/ja/03.2.md @@ -1,8 +1,8 @@ -# 3.2 GOで簡単なwebサーバを立てる +# 3.2 Goで簡単なWebサーバを立てる -前の節でWebはHTTPプロトコルに基づいたサービスであるとご紹介しました。Go言語では完全なnet/httpパッケージを提供しています。httpパッケージを通して実行できるwebサービスを非常に簡単に立ち上げる事ができます。同時にこのパッケージを使用することで、簡単にwebのルーティング、静的なファイル、テンプレート、cookie等のデータに対して設定と操作を行うことができます。 +前の節でWebはhttpプロトコルに基づいたサービスであるとご紹介しました。Go言語では完全なnet/httpパッケージを提供しています。httpパッケージを通して実行できるWebサービスを非常に簡単に立ち上げる事ができます。同時にこのパッケージを使用することで、簡単にWebのルーティング、静的なファイル、テンプレート、cookie等のデータに対して設定と操作を行うことができます。 -## httpパッケージでwebサーバを立てる +## httpパッケージでWebサーバを立てる package main @@ -50,15 +50,15 @@ 図3.8 ユーザがWebにアクセスしてサーバが出力する情報 -上のコードでwebサーバを書くためにはhttpパッケージの2つの関数を呼ぶだけで良いことがわかります。 +上のコードでWebサーバを書くためにはhttpパッケージの2つの関数を呼ぶだけで良いことがわかります。 >もしあなたが以前PHPプログラマであれば。こう問うかもしれません。我々のnginx、apacheサーバは必要ないのですかと?なぜならこいつは直接tcpポートを関ししますので、nginxがsやることをやってくれます。またsayhelloNameは実は我々が書いたロジック関数ですので、phpの中のコントローラ(controller)関数に近いものです。 ->もしあなたがpythonプログラマであったのなら、tornadoを聞いたことがあると思います。このコードはそれとよく似ていませんか?ええ、その通りです。goはpythonのような動的な言語によく似た特性を持っています。webアプリケーションを書くにはとても便利です。 +>もしあなたがPythonプログラマであったのなら、tornadoを聞いたことがあると思います。このコードはそれとよく似ていませんか?ええ、その通りです。GoはPythonのような動的な言語によく似た特性を持っています。Webアプリケーションを書くにはとても便利です。 ->もしあなたがrubyプログラマであったのなら、RORの/script/serverを起動したのと少し似ている事に気づいたかもしれません。 +>もしあなたがRubyプログラマであったのなら、RORの/script/serverを起動したのと少し似ている事に気づいたかもしれません。 -Goを通じて簡単な数行のコードでwebサーバを立ち上げることができました。さらにこのWebサーバの内部ではマルチスレッドの特性をサポートしています。続く2つの節でgoが以下にWebのマルチスレッドを実現しているのか細かくご紹介します。 +Goを通じて簡単な数行のコードでwebサーバを立ち上げることができました。さらにこのWebサーバの内部ではマルチスレッドの特性をサポートしています。続く2つの節でGoが以下にWebのマルチスレッドを実現しているのか細かくご紹介します。 ## links * [目次]() diff --git a/ja/ebook/03.3.md b/ja/03.3.md similarity index 100% rename from ja/ebook/03.3.md rename to ja/03.3.md diff --git a/ja/ebook/03.4.md b/ja/03.4.md similarity index 74% rename from ja/ebook/03.4.md rename to ja/03.4.md index 06da10c8..0af75f10 100644 --- a/ja/ebook/03.4.md +++ b/ja/03.4.md @@ -41,7 +41,7 @@ Goがクライアントのリクエストを待ち受けるには以下のよう ServeHTTP(ResponseWriter, *Request) // ルーティング実現器 } -Handlerはインターフェースですが、前の節の中で`sayhelloName`関数が特にServerHTTPというインターフェースを実装してはいませんでした。どうして追加できるのでしょうか?もともとhttpパッケージの中では`HandlerFunc`という型を定義しています。この型はデフォルトでServerHTTPインターフェースを実装しています。つまり、HandlerFunc(f)をコールして強制的にfをHandlerFunc型に型変換しているのです。このようにしてfはServerHTTPメソッドを持つことになります。 +Handlerはインターフェースですが、前の節の中の`sayhelloName`関数では特にServeHTTPというインターフェースを実装してはいませんでした。どうして追加できるのでしょうか?もともとhttpパッケージの中では`HandlerFunc`という型が定義されています。私達が定義した`sayhelloName`関数はまさにこのHandlerFuncがコールされた結果であり、この型はデフォルトでServeHTTPインターフェースを実装していることになります。つまり、HandlerFunc(f)をコールして強制的にfをHandlerFunc型に型変換しているのです。このようにしてfはServeHTTPメソッドを持つようになります。 type HandlerFunc func(ResponseWriter, *Request) @@ -50,7 +50,7 @@ Handlerはインターフェースですが、前の節の中で`sayhelloName` f(w, r) } -ルータでは対応するルーティングルールを保存した後、具体的にはどのようにリクエストを振り分けているのでしょうか?以下のコードをご覧ください。デフォルトのルータは`ServerHTTP`を実装します: +ルータでは対応するルーティングルールを保存した後、具体的にはどのようにリクエストを振り分けているのでしょうか?以下のコードをご覧ください。デフォルトのルータは`ServeHTTP`を実装します: func (mux *ServeMux) ServeHTTP(w ResponseWriter, r *Request) { if r.RequestURI == "*" { @@ -62,7 +62,7 @@ Handlerはインターフェースですが、前の節の中で`sayhelloName` h.ServeHTTP(w, r) } -上に示す通りルータはリクエストを受け取った後、`*`であれば接続を切断し、そうでなければ`mux.handler(r).ServerHTTP(w, r)`をコールして対応する設定された処理Handlerを返し、`h.ServeHTTP(w, r)`を実行します。 +上に示す通りルータはリクエストを受け取った後、`*`であれば接続を切断し、そうでなければ`mux.handler(r).ServeHTTP(w, r)`をコールして対応する設定された処理Handlerを返し、`h.ServeHTTP(w, r)`を実行します。 つまり、目的のルーティングのhandlerのServerHTTPインターフェースへのコールです。ではmux.Handler(r)はどのように処理するのでしょうか? @@ -93,9 +93,9 @@ Handlerはインターフェースですが、前の節の中で`sayhelloName` return } -もともとこれはユーザのリクエストしたURLとルータの中に保存されているmapのマッチングに従って、このhandlerのServHTTPインターフェースをコールすることで目的の関数を実行することができます。 +もともとこれはユーザのリクエストしたURLとルータの中に保存されているmapに従ってマッチングしています。マッチングによって保存されているhandlerが返されるにあたり、このhandlerのServeHTTPインターフェースがコールされ、目的の関数を実行することができます。 -上の紹介を通じて、ルーティングの全体プロセスを理解しました。これはHandlerインターフェースです。つまり外部のルータはHandlerインターフェースを実装するだけで良く、自分自身で実装したルータのServHTTPの中でカスタムに定義されたルータ機能を実現することができます。 +上の紹介を通して、私達はルーティングの全体プロセスを理解しました。Goは実は外部で実装されたルータをサポートしています。`ListenAndServe`の第2引数が外部のルータを設定する為に用いられます。これはHandlerインターフェースのひとつで、外部ルータでHandlerインターフェースを実装し、そのServeHTTPにカスタム定義のルーティング機能を実装することができます。 下のコードを通して、自分自身で簡単なルータを実装してみます。 @@ -135,11 +135,11 @@ httpパッケージへの分析を通して、全体のコードの実行プロ 順序にしたがっていくつかの事を行います: - 1 DefaultServerMuxのHandlerFuncをコールする。 + 1 DefaultServeMuxのHandlerFuncをコールする。 - 2 DefaultServerMuxのHandleをコールする。 + 2 DefaultServeMuxのHandleをコールする。 - 3 DefaultServerMuxのmap[string]muxEntryで目的のhandlerとルーティングルールを追加する。 + 3 DefaultServeMuxのmap[string]muxEntryで目的のhandlerとルーティングルールを追加する。 - 次にhttp.ListenAndServe(":9090", nil)をコールする。 @@ -161,7 +161,7 @@ httpパッケージへの分析を通して、全体のコードの実行プロ 8 handlerのServeHttpをコールする - 9 この例の中では、この後DefaultServerMux.ServeHttpの中に入ります + 9 この例の中では、この後DefaultServeMux.ServeHttpの中に入ります 10 requestに従ってhandlerを選択し、このhandlerのServeHTTPに入ります @@ -178,4 +178,4 @@ httpパッケージへの分析を通して、全体のコードの実行プロ ## links * [目次]() * 前へ: [Goはどのようにしてweb作業を行うか](<03.3.md>) - * 次へ: [概要](<03.5.md>) + * 次へ: [まとめ](<03.5.md>) diff --git a/ja/ebook/03.5.md b/ja/03.5.md similarity index 96% rename from ja/ebook/03.5.md rename to ja/03.5.md index 94b84f82..fccf5458 100644 --- a/ja/ebook/03.5.md +++ b/ja/03.5.md @@ -1,4 +1,4 @@ -# 3.5 概要 +# 3.5 まとめ この章ではHTTPプロトコル、DNS名前解決のプロセス、どのようにしてgoで簡単なweb serverを実装するかご紹介しました。net/httpパッケージのソースコードに触れるうちにこのserverを実装する秘密についてお分かりいただけたかと思います。 この章の学習を通じて、GoによるWeb開発の初歩をご理解いただければ幸いです。我々はまた対応するコードを見ることでGoでWebアプリケーションを開発することがとても便利でまた相当柔軟であると分かりました。 diff --git a/ja/ebook/04.0.md b/ja/04.0.md similarity index 97% rename from ja/ebook/04.0.md rename to ja/04.0.md index 9a887076..328d854f 100644 --- a/ja/ebook/04.0.md +++ b/ja/04.0.md @@ -21,5 +21,5 @@ HTTPプロトコルはステートレスなプロトコルです。ではどの ## links * [目次]() - * 前へ: [第三章概要](<03.5.md>) + * 前へ: [第三章まとめ](<03.5.md>) * 次へ: [フォームの入力を処理する](<04.1.md>) diff --git a/ja/ebook/04.1.md b/ja/04.1.md similarity index 100% rename from ja/ebook/04.1.md rename to ja/04.1.md diff --git a/ja/ebook/04.2.md b/ja/04.2.md similarity index 95% rename from ja/ebook/04.2.md rename to ja/04.2.md index 7228afbb..6e22ee03 100644 --- a/ja/ebook/04.2.md +++ b/ja/04.2.md @@ -38,14 +38,14 @@ Webアプリケーションを書く時は主に2つの方面のデータ検 >Goの正規表現の実装は[RE2](http://code.google.com/p/re2/wiki/Syntax)です。すべての文字はUTF-8エンコーディングです。 -## 中文 -フォームの要素からユーザの中国語名を得たい場合で、なおかつ正しい中国語であることを保証したい場合、検証を行う必要があります。ユーザに自由に入力はさせません。中国語に対する有効な検証方法は今のところ正規表現しかありません。下のコードをご確認ください +## 中国語 +フォームの要素からユーザの中国語名を得たい場合で、なおかつ正しい中国語であることを保証したい場合、検証を行う必要があります。ユーザに自由に入力はさせません。中国語に対する有効な検証には、`unicode` パッケージが提供する `func Is(rangeTab *RangeTable, r rune) bool` と正規表現を使う方法があります。下のコードをご確認ください - if m, _ := regexp.MatchString("^[\\x{4e00}-\\x{9fa5}]+$", r.Form.Get("realname")); !m { + if m, _ := regexp.MatchString("^\\p{Han}+$", r.Form.Get("realname")); !m { return false } -## 英文 +## 英語 あるユーザの英語名を知りたいときなど、フォームの要素から英語の値を取り出したい場合は、astaxieであってasta谢ではないはずです。(訳注:「谢」はピンインでxieと書く) 簡単な正規表現を使ってデータを検証することができます: diff --git a/ja/ebook/04.3.md b/ja/04.3.md similarity index 100% rename from ja/ebook/04.3.md rename to ja/04.3.md diff --git a/ja/ebook/04.4.md b/ja/04.4.md similarity index 100% rename from ja/ebook/04.4.md rename to ja/04.4.md diff --git a/ja/ebook/04.5.md b/ja/04.5.md similarity index 96% rename from ja/ebook/04.5.md rename to ja/04.5.md index 9e109411..826bb052 100644 --- a/ja/ebook/04.5.md +++ b/ja/04.5.md @@ -113,7 +113,8 @@ fmt.Println("error opening file") return err } - + defer fh.Close() + //iocopy _, err = io.Copy(fileWriter, fh) if err != nil { @@ -152,4 +153,4 @@ ## links * [目次]() * 前へ: [フォームの多重送信の防止](<04.4.md>) - * 次へ: [概要](<04.6.md>) + * 次へ: [まとめ](<04.6.md>) diff --git a/ja/ebook/04.6.md b/ja/04.6.md similarity index 97% rename from ja/ebook/04.6.md rename to ja/04.6.md index e3b349da..bc8c035e 100644 --- a/ja/ebook/04.6.md +++ b/ja/04.6.md @@ -1,4 +1,4 @@ -# 4.6 概要 +# 4.6 まとめ この一章ではGoでどのようにフォームの情報を処理するか学びました。ユーザのログインから、ファイルのアップロードの例で、Goがformの情報およびファイルをアップロードする手段についてご説明しました。しかし、フォームを処理する過程ではユーザの入力した情報を懸賞する必要があります。ホームページのセキュリティの重要性を考慮すると、データのフィルタリングは相当重要です。そのため、以降の章では異なる方面のデータフィルタリングをご説明します。同時にGoの文字列に対する正規表現についても述べます。 この一章を通してクライアントとサーバが如何にデータを互いにやりとりするか理解いただけたと思います。クライアントはデータをサーバシステムに渡し、サーバはデータを受け取って結果をクライアントにフィードバックします。 diff --git a/ja/ebook/05.0.md b/ja/05.0.md similarity index 90% rename from ja/ebook/05.0.md rename to ja/05.0.md index cf8108e8..3fa1552a 100644 --- a/ja/ebook/05.0.md +++ b/ja/05.0.md @@ -5,10 +5,12 @@ Goはどのようなデータベースの使用もbuiltinではサポートさ 現在NOSQLはすでにWeb開発の流行となっています。多くのアプリケーションがNOSQLをデータベースとして採用しています。以前のキャッシュではありません。5.6節ではMongoDBとRedisの2つのNOSQLデータベースについてご紹介します。 +>[Go database/sql tutorial](http://go-database-sql.org/)ではよく使われる例と詳細な説明を提供しています。 + ## 目次 ![](images/navi5.png?raw=true) ## links * [目次]() - * 前へ: [第四章概要](<04.6.md>) + * 前へ: [第四章まとめ](<04.6.md>) * 次へ: [database/sqlインターフェース](<05.1.md>) diff --git a/ja/ebook/05.1.md b/ja/05.1.md similarity index 92% rename from ja/ebook/05.1.md rename to ja/05.1.md index 69801941..8122cccb 100644 --- a/ja/ebook/05.1.md +++ b/ja/05.1.md @@ -1,5 +1,5 @@ # 5.1 database/sqlインターフェース -GoのPHPと異なる部分は、Goにはオフィシャルが提供するデーターベースドライバを持っていない事です。開発者が開発するためにデータベースドライバで標準のインターフェースが定義されています。開発者は定義されているインターフェースに従って目的のデータベースドライバを開発することができます。これにはメリットがあります。標準のインターフェースを参照するだけでコードを開発できます。以降データベースに遷移する時、どのような修正も必要ありません。では、Goはどのような標準インターフェースを定義しているのでしょうか?詳しく分析してみることにしましょう。 +GoがPHPと異なる部分は、Goには公式に提供されたデータベースドライバがない事です。開発者が開発するためにデータベースドライバで標準のインターフェースが定義されています。開発者は定義されているインターフェースに従って目的のデータベースドライバを開発することができます。これにはメリットがあります。標準のインターフェースを参照するだけでコードを開発できます。以降データベースに移行する時、どのような修正も必要ありません。では、Goはどのような標準インターフェースを定義しているのでしょうか?詳しく分析してみることにしましょう。 ## sql.Register database/sqlに存在する関数はデータベースドライバを登録するためにあります。サードパーティの開発者がデータベースドライバを開発する時は、すべてinit関数を実装します。init関数ではこの`Register(name string, driver driver.Driver)`をコールすることでこのドライバの登録を完了させます。 @@ -138,7 +138,7 @@ Next関数はひとつのデータを返すのに用いられます。データ ## driver.RowsAffected -RowsAffestedは実はint64のエイリアスです。しかしResultインターフェースを実装していますので、低レイヤーでResultの表示メソッドを実装するために用いられます。 +RowsAffectedは実はint64のエイリアスです。しかしResultインターフェースを実装していますので、低レイヤーでResultの表示メソッドを実装するために用いられます。 type RowsAffected int64 diff --git a/ja/ebook/05.2.md b/ja/05.2.md similarity index 91% rename from ja/ebook/05.2.md rename to ja/05.2.md index 7998e139..b6cc71b2 100644 --- a/ja/ebook/05.2.md +++ b/ja/05.2.md @@ -37,7 +37,7 @@ GoではMySQLをサポートしたドライバが現在比較的多く、以下 package main import ( - _ "github.com/Go-SQL-Driver/MySQL" + _ "github.com/go-sql-driver/mysql" "database/sql" "fmt" //"time" @@ -114,7 +114,7 @@ GoではMySQLをサポートしたドライバが現在比較的多く、以下 キーとなるいくつかの関数についてご説明します: -sql.Open()関数は登録済みのデータベースドライバを開くために使用されます。Go-MySQL-Driverの中でmysqlのデータベースドライバを登録し、2つ目の引数はDSN(Data Source Name)です。これはGo-MySQL-Driverが定義するデータベース接続と設定情報です。以下のシンタックスをサポートします: +sql.Open()関数は登録済みのデータベースドライバを開くために使用されます。go-sql-driverの中でmysqlのデータベースドライバを登録し、2つ目の引数はDSN(Data Source Name)です。これはgo-sql-driverが定義するデータベース接続と設定情報です。以下のシンタックスをサポートします: user@unix(/path/to/socket)/dbname?charset=utf8 user:password@tcp(localhost:5555)/dbname?charset=utf8 diff --git a/ja/ebook/05.3.md b/ja/05.3.md similarity index 94% rename from ja/ebook/05.3.md rename to ja/05.3.md index 736a2687..3c643d9a 100644 --- a/ja/ebook/05.3.md +++ b/ja/05.3.md @@ -1,6 +1,6 @@ # 5.3 SQLiteデータベースの使用 -SQLiteはオープンソースの組み込み式リレーショナルデータベースです。独立しており、設定なしでトランザクションのSQLデータベースエンジンをサポートします。非常にポータブルで簡単に利用でき、コンパクトで効率が高く、信頼性があります。他のデータベース管理システムとは異なり、SQLiteのインストールと実行は非常に簡単です。多くの場合は、ただSQLiteのバイナリファイルを用意するだけですぐに作成、接続、使用することができます。もしあなたが現在組み込み式データベースかソリューションをお探しであれば、SQLいては絶対に考慮するに値します。SQLiteはいわばオープンソースのAccessのようなものです。 +SQLiteはオープンソースの組み込み式リレーショナルデータベースです。独立しており、設定なしでトランザクションのSQLデータベースエンジンをサポートします。非常にポータブルで簡単に利用でき、コンパクトで効率が高く、信頼性があります。他のデータベース管理システムとは異なり、SQLiteのインストールと実行は非常に簡単です。多くの場合は、ただSQLiteのバイナリファイルを用意するだけですぐに作成、接続、使用することができます。もしあなたが現在組み込み式データベースかソリューションをお探しであれば、SQLiteは絶対に考慮するに値します。SQLiteはいわばオープンソースのAccessのようなものです。 ## ドライバ Goがサポートするsqliteのドライバも比較的多いのですが、大部分はdatabase/sqlインターフェースをサポートしていません。 diff --git a/ja/ebook/05.4.md b/ja/05.4.md similarity index 94% rename from ja/ebook/05.4.md rename to ja/05.4.md index 8012669a..05e2936a 100644 --- a/ja/ebook/05.4.md +++ b/ja/05.4.md @@ -9,7 +9,7 @@ MySQLはOracleに買収され、現在徐々にクローズされつつありま ## ドライバ GoはPostgreSQLをサポートしたドライバも非常に多く実装されています。国外では多くの人が開発でこのデータベースを使用しているためです。 -- https://github.com/bmizerany/pq database/sqlドライバをサポートしています。純粋にGoで書かれています。 +- 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で書かれています。 @@ -43,7 +43,7 @@ package main import ( "database/sql" "fmt" - _ "github.com/bmizerany/pq" + _ "https://github.com/lib/pq" ) func main() { diff --git a/ja/ebook/05.5.md b/ja/05.5.md similarity index 97% rename from ja/ebook/05.5.md rename to ja/05.5.md index 620328b8..f9ef783c 100644 --- a/ja/ebook/05.5.md +++ b/ja/05.5.md @@ -84,7 +84,7 @@ beedbインターフェースはもう一種類の挿入の方法を提供して 複数のデータを挿入 - addslice := make([]map[string]interface{}) + addslice := make([]map[string]interface{}, 0) add:=make(map[string]interface{}) add2:=make(map[string]interface{}) add["username"] = "astaxie" diff --git a/ja/ebook/05.6.md b/ja/05.6.md similarity index 97% rename from ja/ebook/05.6.md rename to ja/05.6.md index fc6aac61..36c80693 100644 --- a/ja/ebook/05.6.md +++ b/ja/05.6.md @@ -111,4 +111,4 @@ mgoの操作方法とbeedbの操作方法はほとんど似ていることがわ ## links * [目次]() * 前へ: [beedbライブラリを使用してORM開発を行う](<05.5.md>) - * 次へ: [概要](<05.7.md>) + * 次へ: [まとめ](<05.7.md>) diff --git a/ja/ebook/05.7.md b/ja/05.7.md similarity index 88% rename from ja/ebook/05.7.md rename to ja/05.7.md index 33371d44..a1244ce0 100644 --- a/ja/ebook/05.7.md +++ b/ja/05.7.md @@ -1,8 +1,10 @@ -# 5.7 概要 +# 5.7 まとめ この章ではGoがどのようにdatabase/sqlインターフェースを設計するのかご説明しました。その後、サードパーティによるリレーショナルデータベースドライバの使用をご紹介しました。次にbeedbというリレーショナルデータベースに基づくORMライブラリがどのようにしてデータベースに対して簡単な操作を行うかご説明しました。最後にNOSQLのいくつかの知識をご紹介しました。現在GoのNOSQLに対するサポートはなかなかよくできています。Goは21世紀のC言語ですから、21世紀のデータベースに対するサポートも非常によくできています。 この一章の学習を通じて、いろいろなデータベースをどのように操作するか学んできました。Webの中でも重要なデータの保存に関する問題が解決したので、みなさんのdatabase/sqlの設計思想により一歩進んだ理解が深まることを願っています。 +>[Go database/sql tutorial](http://go-database-sql.org/)ではよく使われる例と詳細な説明を提供しています。 + ## links * [目次]() * 前へ: [NOSQLデータベースの操作](<05.6.md>) diff --git a/ja/ebook/06.0.md b/ja/06.0.md similarity index 90% rename from ja/ebook/06.0.md rename to ja/06.0.md index 0d381ce7..136d067e 100644 --- a/ja/ebook/06.0.md +++ b/ja/06.0.md @@ -1,12 +1,12 @@ # 6 sessionとデータの保存 Web開発ではどのようにしてユーザの閲覧過程のすべてをコントロールするかということは非常に重要です。HTTPプロトコルはステートレスですので、ユーザの毎回のリクエストにはステータスがありません。Web操作の全体の過程の中でどの接続がどのユーザと関係しているのか知る方法がありません。では、どのようにしてこの問題を解決しているのでしょうか?Webでの伝統的な解決方法はcookieとsessionです。cookieによるメカニズムはクライアント側でのメカニズムです。ユーザのデータをクライアントに保存します。sessionメカニズムはサーバ側でのメカニズムです。サーバはハッシュテーブルのような構造でデータを保存します。ホームページの各閲覧者はユニークなIDを与えられます。すなわち、SessionIDです。この保存形式は2つだけです:urlによって渡されるか、クライアントのcookieに保存されるかです。当然、Sessionをデータベースに保存することもできます。よりセキュリティが高まりますが、効率の面ではいくつか後退します。 -6.1節ではsessionメカニズムとcookieメカニズムの関係と区別についてご紹介します。6.2ではGo言語がどのようにsessionを実現しているかご説明します。この中では簡単なsessionマネージャを実現します。6.3節ではどのようにしてsessionハイジャックの状態を防ぐかご説明します。どのように効果的にsessionを保護するのか。sessionはそもそもどのようなところに保存してもよいのです。6.3節ではsessionをメモリの中に保存しますが、我々のアプリケーションをもう一歩展開させる場合、アプリケーションのsession共有を実現する必要があります。sessionをデータベースの中(memcacheまたはredis)に保存します。6.4節ではどのようにしてこの機能を実装するかご説明します。 +6.1節ではsessionメカニズムとcookieメカニズムの関係と区別についてご紹介します。6.2ではGo言語がどのようにsessionを実現しているかご説明します。この中では簡単なsessionマネージャを実現します。6.3節ではどのようにしてsessionハイジャックの状態を防ぐかご説明します。どのように効果的にsessionを保護するのか。sessionはそもそもどのようなところに保存してもよいのです。6.3節ではsessionをメモリの中に保存しますが、我々のアプリケーションをもう一歩展開させる場合、アプリケーションのsession共有を実現する必要があります。sessionをデータベースの中(memcachedまたはredis)に保存します。6.4節ではどのようにしてこの機能を実装するかご説明します。 ## 目次 ![](images/navi6.png?raw=true) ## links * [目次]() - * 前へ: [第五章概要](<05.7.md>) + * 前へ: [第五章まとめ](<05.7.md>) * 次へ: [sessionとcookie](<06.1.md>) diff --git a/ja/ebook/06.1.md b/ja/06.1.md similarity index 98% rename from ja/ebook/06.1.md rename to ja/06.1.md index 4367300b..6107f369 100644 --- a/ja/ebook/06.1.md +++ b/ja/06.1.md @@ -60,8 +60,8 @@ wは入力する必要のあるresponse、cookieはstructです。cookieオブ 例を一つ見てみましょう。どのようにcookieを設定するかです。 - expiration := *time.LocalTime() - expiration.Year += 1 + expiration := time.Now() + expiration = expiration.AddDate(1, 0, 0) cookie := http.Cookie{Name: "username", Value: "astaxie", Expires: expiration} http.SetCookie(w, &cookie) @@ -92,7 +92,7 @@ sessionメカニズムはサーバサイドのメカニズムです。サーバ sessionメカニズム自身は特に複雑ではありませんが、その実装と設定の柔軟性は複雑を極めます。これは一回の経験やひとつのブラウザ、サーバのみの経験でもって普遍的に通用するものではありません。 -## 概要 +## まとめ 上述の通り、sessionとcookieの目的は同じです。どちらもhttpプロトコルのステートレスであるという欠点を克服するためにあります。しかしその方法は異なります。sessionはcookieを通じてクライアントにsession idを保存します。またユーザの他のセッション情報はサーバのsessionオブジェクトに保存されます。これとは対照的に、cookieはすべての情報をクライアントに持たせる必要があります。そのためcookieにはある程度潜在的な脅威が存在します。例えばローカルのcookieに保存されたユーザ名とパスワードが解読されたり、cookieが他のホームページに収集されます(例えば:1.appAが主導的にゾーンBのcookieを設定し、ゾーンBにcookieを取得させます;2.XSS、appAでjavascriptを通じてdocument.cookieを取得し、自分のappBに送信します)。 diff --git a/ja/ebook/06.2.md b/ja/06.2.md similarity index 98% rename from ja/ebook/06.2.md rename to ja/06.2.md index 1ed609fa..d295d71b 100644 --- a/ja/ebook/06.2.md +++ b/ja/06.2.md @@ -206,7 +206,7 @@ Webアプリケーションにはユーザのログアウト操作がありま GCが十分にtimeパッケージのタイマー機能を利用していることがおわかりいただけるかと思います。時間が`maxLifeTime`を超えた後GC関数をコールした際、これによって`maxLiefTime`時間内でsessionが利用できることを保証できます。このような方法はまたオンラインユーザの数といった統計に用いることもできます。 -## 概要 +## まとめ これまでに、WebアプリケーションにおけるグローバルなSession管理に用いられるSessionManagerを実装してまいりました。Sessionを提供するために用いられるストレージを定義し、Providerのインターフェースを実装しました。次の節では、インターフェースの定義を通してProviderを実装します。ぜひご参考ください。 ## links diff --git a/ja/ebook/06.3.md b/ja/06.3.md similarity index 100% rename from ja/ebook/06.3.md rename to ja/06.3.md diff --git a/ja/ebook/06.4.md b/ja/06.4.md similarity index 98% rename from ja/ebook/06.4.md rename to ja/06.4.md index e5876b83..312bbae8 100644 --- a/ja/ebook/06.4.md +++ b/ja/06.4.md @@ -86,4 +86,4 @@ sessionが始まると、生成されたsessionIDの時間を記録する一つ ## links * [目次]() * 前へ: [sessionストレージ](<06.3.md>) - * 次へ: [概要](<06.5.md>) + * 次へ: [まとめ](<06.5.md>) diff --git a/ja/ebook/06.5.md b/ja/06.5.md similarity index 98% rename from ja/ebook/06.5.md rename to ja/06.5.md index db31bdba..c9e71eae 100644 --- a/ja/ebook/06.5.md +++ b/ja/06.5.md @@ -1,4 +1,4 @@ -# 6.5 概要 +# 6.5 まとめ この章ではsession/cookieとは何かを、また両者の関係について勉強しました。しかし現在Goのオフィシャルパッケージではsessionがサポートされていません。そのため、sessionマネージャを設計しました。sessionの作成から破棄に至る全体の過程を実装し、Providerのインターフェースを定義することによって、各バックエンドのsessionストレージをサポートできるようにしました。第三節ではメモリストレージによってどのようにsessionの管理を実装するのかご紹介しました。第四節ではsessionハイジャックの過程と、どのようにsessionハイジャックを防止するのかを解説しました。第一章の解説を通して、読者の皆様方にはsessionの実行原理とどのように実現されるか、またどのように安全にsessionを使用するかについて理解いただけるよう望んています。 ## links * [目次]() diff --git a/ja/ebook/07.0.md b/ja/07.0.md similarity index 92% rename from ja/ebook/07.0.md rename to ja/07.0.md index 88daddd0..78bb7af9 100644 --- a/ja/ebook/07.0.md +++ b/ja/07.0.md @@ -1,12 +1,12 @@ # 7 テキスト処理 Web開発においてテキスト処理は非常に重要な要素です。往々にして出力または入力する内容に対して処理を行う必要があります。ここでのテキストには文字列、数字、Json、XML等々が含まれます。高性能な一言語としてのGo言語では、これらのテキストの処理はすべてオフィシャルの標準パッケージにサポートされています。また利用中にGo標準ライブラリが巧みに設計されていることに気がつくでしょう。またユーザからすれば非常に簡単にこれらのテキストを処理することができます。本章では4つの節を通してユーザにGo言語のテキスト処理のよい知識をご紹介したいきたいと思います。 -XMLは現在多くの標準インターフェースの対話型言語となっています。多くの場合Javaで書かれたwebserverとのやりとりはどれもXML標準にもとづいて行われます。7.1節ではどのようにXMLテキストを処理するかご紹介します。XMLを使用した後あまりに複雑だと気づきます。現在多くのインターネット企業の対外的なAPIでは多くがJSON形式を採用しています。この形式は描写が簡単ですが、意味をよく表現することができます。7.2節ではどのようにこういったJSON形式のデータを処理するかご説明します。正規表現は人に愛され、また恨まれる道具です。このテキスト処理能力は非常に協力です。我々は前のフォームの検証でその強力さをすでに味わっています。7.3節ではどのようにGoの正規表現を利用するのがよいかより詳しく解説していきます。Web開発において非常に重要な部分としてMVCの分離があります。Go言語ではWeb開発中Vにおいて`template`という専門的にサポートするパッケージがあります。7.4節ではテンプレートをつかってコンテンツをどのように出力するのか詳細に解説していきます。7.5節ではどのようにしてファイルとディレクトリを操作するのか詳しくご紹介します。7.6節の概要では文字列に関する操作についてご紹介します。 +XMLは現在多くの標準インターフェースの対話型言語となっています。多くの場合Javaで書かれたwebserverとのやりとりはどれもXML標準にもとづいて行われます。7.1節ではどのようにXMLテキストを処理するかご紹介します。XMLを使用した後あまりに複雑だと気づきます。現在多くのインターネット企業の対外的なAPIでは多くがJSON形式を採用しています。この形式は描写が簡単ですが、意味をよく表現することができます。7.2節ではどのようにこういったJSON形式のデータを処理するかご説明します。正規表現は人に愛され、また恨まれる道具です。このテキスト処理能力は非常に協力です。我々は前のフォームの検証でその強力さをすでに味わっています。7.3節ではどのようにGoの正規表現を利用するのがよいかより詳しく解説していきます。Web開発において非常に重要な部分としてMVCの分離があります。Go言語ではWeb開発中Vにおいて`template`という専門的にサポートするパッケージがあります。7.4節ではテンプレートをつかってコンテンツをどのように出力するのか詳細に解説していきます。7.5節ではどのようにしてファイルとディレクトリを操作するのか詳しくご紹介します。7.6節のまとめでは文字列に関する操作についてご紹介します。 ## 目次 ![](images/navi7.png?raw=true) ## links * [目次]() - * 前へ: [第六章概要](<06.5.md>) + * 前へ: [第六章まとめ](<06.5.md>) * 次へ: [XMLの処理](<07.1.md>) diff --git a/ja/ebook/07.1.md b/ja/07.1.md similarity index 100% rename from ja/ebook/07.1.md rename to ja/07.1.md diff --git a/ja/ebook/07.2.md b/ja/07.2.md similarity index 100% rename from ja/ebook/07.2.md rename to ja/07.2.md diff --git a/ja/ebook/07.3.md b/ja/07.3.md similarity index 96% rename from ja/ebook/07.3.md rename to ja/07.3.md index b5a33e61..fd24113a 100644 --- a/ja/ebook/07.3.md +++ b/ja/07.3.md @@ -69,23 +69,23 @@ Matchパターンは文字列の判断に対してのみ使うことができ、 src := string(body) - //将HTML标签全转换成小写 + //HTMLタグを全て小文字に変換します re, _ := regexp.Compile("\\<[\\S\\s]+?\\>") src = re.ReplaceAllStringFunc(src, strings.ToLower) - //去除STYLE + //