More Related Content Similar to Go言語によるwebアプリの作り方 (20) More from Yasutaka Kawamoto (8) Go言語によるwebアプリの作り方2. 自己紹介
• 河本 泰孝 @kwmt27
• 車関連の仕事やってます。
• androg.seesaa.net ブログ書いてます。
• 私とGo言語との関わり
• 2011年のDevQuizで初めて触った
• 2012年1月のGo言語勉強会に参加
• 2012年4月の東海GTUGさんのGAE勉強会でGoを使った
• 2012年8月のGDG神戸でGo言語のスライスについて発表
• 2012年10月,2013年1月GDG名古屋のスタートGo#0,#1に
参加
Creative Commons Attribution 3.0 License
3. 自己紹介
• 最近では公式サイトの
• Writing Web Applications
• Go Slices
を翻訳してみたり。
https://github.com/kwmt/
golangwiki
↑↑ forkして一緒に翻訳しませんか?
Creative Commons Attribution 3.0 License
11. Go言語の特徴&紹介
公式サイト http://golang.org
Go version 1
翻訳サイト http://golang.jp/ 未対応箇所あるので注意
Go Playground http://play.golang.org/
A Tour of Go http://go-tour-jp.appspot.com
golang-nuts
http://groups.google.com/group/golang-nuts
golang-jp
https://groups.google.com/forum/#!forum/
golang-jp Creative Commons Attribution 3.0 License
15. 基本1
package main
import "fmt"
func main() {
var hello string = "Hello, 世界!"
//hello := “Hello, 世界!”
String(hello)
}
func String(s string) {
fmt.Println(s)
}
Creative Commons Attribution 3.0 License
16. package から始まります
基本1
package main
import "fmt"
func main() {
var hello string = "Hello, 世界!"
//hello := “Hello, 世界!”
String(hello)
}
func String(s string) {
fmt.Println(s)
}
Creative Commons Attribution 3.0 License
17. 基本1 グループ化できます
import(
パッケージを読み込みます “fmt”
package main “io/iouti.”
)
import "fmt"
func main() {
var hello string = "Hello, 世界!"
//hello := “Hello, 世界!”
String(hello)
}
func String(s string) {
fmt.Println(s)
}
Creative Commons Attribution 3.0 License
18. 基本1
main関数が最初に呼び
出されます
package main
main関数があるpackageはmainでなければ
import "fmt" なりません
func main() {
var hello string = "Hello, 世界!"
//hello := “Hello, 世界!”
String(hello)
}
func String(s string) {
fmt.Println(s)
}
Creative Commons Attribution 3.0 License
19. 基本1
package main
import "fmt"
文末に
func main() { セミコロン不要
var hello string = "Hello, 世界!"
//hello := “Hello, 世界!”
String(hello)
}
func String(s string) {
fmt.Println(s)
}
Creative Commons Attribution 3.0 License
20. 基本1
package main
import "fmt"
func main() { := だけで定義できる
var hello string = "Hello, 世界!"
(型推論)
//hello := “Hello, 世界!”
String(hello)
}
func String(s string) {
fmt.Println(s)
}
Creative Commons Attribution 3.0 License
21. 基本1
package main
import "fmt"
func main() {
var hello string = "Hello, 世界!"
//hello := “Hello, 世界!”
String(hello) 関数定義
} プロトタイプ宣言不要
func String(s string) {
fmt.Println(s) 値渡し
}
Creative Commons Attribution 3.0 License
22. 基本1
package main
import "fmt"
func main() {
var hello string = "Hello, 世界!"
//hello := “Hello, 世界!”
String(hello)
}
パッケージ名.(ドット)関数名で
func String(s string) {
fmt.Println(s) パッケージの関数を呼び出す
}
Creative Commons Attribution 3.0 License
23. 基本2
func main() {
for i:=0;i<10;i++{
if i%2!=0 {
fmt.Printf("%dは奇数n",i)
}
}
}
Creative Commons Attribution 3.0 License
24. 基本2
for文、if文は()不要
ループはfor文だけ
func main() {
for i:=0;i<10;i++{
if i%2!=0 {
fmt.Printf("%dは奇数n",i)
}
}
}
Creative Commons Attribution 3.0 License
25. 基本2
for文、if文は()不要
ループはfor文だけ
func main() {
for i:=0;i<10;i++{
if i%2!=0 {
fmt.Printf("%dは奇数n",i) 文法ではないですが
} $go fmt for.go
} で綺麗になります
}
func main() {
! for i := 0; i < 10; i++ {
! ! if i%2 != 0 {
! ! ! fmt.Printf("%dは奇数n", i)
! ! }
! }
Creative Commons Attribution 3.0 License
27. 基本4
構造体
type MyData struct {
name string //名前
Height int //身長
}
メソッド
func (data *Mydata) SetName(name string) {
data.name = name
}
Creative Commons Attribution 3.0 License
28. 言い忘れてましたが、構造体に限らず、
基本4
変数名の最初の文字が
大文字と小文字に意味があります。
構造体
type MyData struct {
name string //名前
Height int //身長
}
メソッド
func (data *Mydata) SetName(name string) {
data.name = name
}
Creative Commons Attribution 3.0 License
29. 言い忘れてましたが、構造体に限らず、
基本4
変数名の最初の文字が
大文字と小文字に意味があります。
構造体
type MyData struct { javaで言うところ、
name string //名前
大文字がpublicで、
Height int //身長
} 小文字がprivateです。
メソッド
func (data *Mydata) SetName(name string) {
data.name = name
}
Creative Commons Attribution 3.0 License
30. 基本4
構造体
type MyData struct {
name string //名前
Height int //身長
} 関数の一種だが、特定の型
と関連づけることが可能
(thisとかselfとかはない)
メソッド
func (data *Mydata) SetName(name string) {
data.name = name
}
Creative Commons Attribution 3.0 License
40. wikiの仕様
http://localhost:8080/edit/sample
/view/sample
Title Title
Editing sample sample
sample body [edit]
sample body
Body Body
Save
DB代わり
リダイレクト
/save/sample
sample.txtを作成し、内容を保存
Creative Commons Attribution 3.0 License
47. ハンドラの登録
webページに出力させるには、
ハンドラを登録する必要があります。
package main
import "net/http"
func viewHandler(w http.ResponseWriter, r *http.Request){
fmt.Fprintf(w, “Hello, %q”, r.URL.Path[1:])
}
func main() {
http.HandleFunc(“/”, viewHandler)
http.ListenAndServe(":8080",nil)
}
Creative Commons Attribution 3.0 License
48. ハンドラの登録
webページに出力させるには、
ハンドラを登録する必要があります。
package main
import "net/http"
func viewHandler(w http.ResponseWriter, r *http.Request){
fmt.Fprintf(w, “Hello, %q”, r.URL.Path[1:])
}
func main() { ↓”/”にviewHandlerを登録
http.HandleFunc(“/”, viewHandler)
http.ListenAndServe(":8080",nil)
}
Creative Commons Attribution 3.0 License
51. http.Request
func viewHandler(w http.ResponseWriter, r *http.Request){
fmt.Fprintf(w, “Hello, %q”, r.URL.Path)
}
type URL struct {
Scheme string
type Request struct{ Opaque string
Method string User *Userinfo
URL *url.URL Host string
... ↑net/urlパッケージ Path string
Form url.Values RawQuery string
... Fragment string
} }
Creative Commons Attribution 3.0 License
52. http.Request
func viewHandler(w http.ResponseWriter, r *http.Request){
fmt.Fprintf(w, “Hello, %q”, r.URL.Path)
}
type URL struct {
Scheme string
type Request struct{ Opaque string
Method string User *Userinfo
URL *url.URL Host string
... ↑net/urlパッケージ Path string
Form url.Values RawQuery string
... Fragment string
} }
URLは次のような形を表現しています。
scheme://[userinfo@]host/path[?query][#fragment]
Creative Commons Attribution 3.0 License
58. HTMLを生成
http://localhost:8080/view/sample sample Title
にアクセスがあった時に、
[edit]
sample.txtを読み込み、
sample body Body
右図のように表示したい。
func viewHandler(w http.ResponseWriter, r *http.Request) {
! title := r.URL.Path[6:]
! p, _ := loadPage(title)
! fmt.Fprintf(w, "<h1>%s</h1><p>[<a href="/edit/%s
">edit</a>]</p><div>%s</div>",
p.Title, p.Title, p.Body)
}
Creative Commons Attribution 3.0 License
59. HTMLを生成
http://localhost:8080/view/sample sample Title
にアクセスがあった時に、
[edit]
sample.txtを読み込み、
sample body Body
右図のように表示したい。
func viewHandler(w http.ResponseWriter, r *http.Request) {
! title := r.URL.Path[6:]
! p, _ := loadPage(title)
! fmt.Fprintf(w, "<h1>%s</h1><p>[<a href="/edit/%s
">edit</a>]</p><div>%s</div>",
p.Title, p.Title, p.Body)
}
Creative Commons Attribution 3.0 License
60. HTMLを生成
http://localhost:8080/view/sample sample Title
にアクセスがあった時に、
[edit]
sample.txtを読み込み、
sample body Body
右図のように表示したい。
このようなHTMLの
ハードコーディングはダサいですよね。
func viewHandler(w http.ResponseWriter, r *http.Request) {
いい方法がありますよ。奥さん
! title := r.URL.Path[6:]
! p, _ := loadPage(title)
! fmt.Fprintf(w, "<h1>%s</h1><p>[<a href="/edit/%s
">edit</a>]</p><div>%s</div>",
p.Title, p.Title, p.Body)
}
Creative Commons Attribution 3.0 License
65. HTMLを生成
“text/template”パッケージを使います。
template : <p>Hello, {{.Title}}</p>
Hello, sample
struct : Page{Title:”sample”}
func viewHandler(w *http.ResponseWriter, r *http.Request){
! title := r.URL.Path[6:]
! p, _ := loadPage(title)
t, _ := tempalte.ParseFiles(“view.html”)
t.Execute(w, p)
}
Creative Commons Attribution 3.0 License
66. HTMLを生成
“text/template”パッケージを使います。
template : <p>Hello, {{.Title}}</p>
Hello, sample
struct : Page{Title:”sample”}
func viewHandler(w *http.ResponseWriter, r *http.Request){
! title := r.URL.Path[6:]
! p, _ := loadPage(title)
t, _ := tempalte.ParseFiles(“view.html”)
t.Execute(w, p)
}
Creative Commons Attribution 3.0 License
67. HTMLを生成
“text/template”パッケージを使います。
template : <p>Hello, {{.Title}}</p>
Hello, sample
struct : Page{Title:”sample”}
Template構造体を作成しパースします
func viewHandler(w *http.ResponseWriter, r *http.Request){
*Templateとerror を返します
! title := r.URL.Path[6:]
! p, _ := loadPage(title)
t, _ := tempalte.ParseFiles(“view.html”)
t.Execute(w, p)
}
Creative Commons Attribution 3.0 License
68. HTMLを生成
“text/template”パッケージを使います。
template : <p>Hello, {{.Title}}</p>
Hello, sample
struct : Page{Title:”sample”}
パースされたテンプレート tを
Template構造体を作成しパースします
pに適用して、
func viewHandler(w *http.ResponseWriter, r *http.Request){
*Templateとerror を返します
! title := r.URL.Path[6:]
wに出力します
! p, _ := loadPage(title)
t, _ := tempalte.ParseFiles(“view.html”)
t.Execute(w, p)
}
Creative Commons Attribution 3.0 License
69. HTMLを生成
“text/template”パッケージを使います。
template : <p>Hello, {{.Title}}</p>
Hello, sample
struct : Page{Title:”sample”}
パースされたテンプレート tを
Template構造体を作成しパースします
pに適用して、
func viewHandler(w *http.ResponseWriter, r *http.Request){
*Templateとerror を返します
! title := r.URL.Path[6:]
wに出力します
! p, _ := loadPage(title)
t, _ := tempalte.ParseFiles(“view.html”)
t.Execute(w, p)
} 先ほどハードコーディングされた
HTMLを別ファイルに書く(あとで)
Creative Commons Attribution 3.0 License
74. HTMLを生成 /edit/sample
Editing sample
次にeditページを作成します。
edit.htmlを次のようにしましょう。
Save
Creative Commons Attribution 3.0 License
75. HTMLを生成 /edit/sample
Editing sample
次にeditページを作成します。
edit.htmlを次のようにしましょう。
<h1>Editing {{.Title}}</h1> Save
<form action="/save/{{.Title}}" method="POST">
<div><textarea name="body" rows="20" cols="80">
{{printf "%s" .Body}}
</textarea></div>
<div><input type="submit" value="Save"></div>
</form>
Creative Commons Attribution 3.0 License
84. どこまでできた?
http://localhost:8080/edit/sample
/view/sample
editHandler
Title Title
Editing sample edit.html sample viewHandler
view.html
sample body [edit]
sample body
Body Body
Save
/save/sample
sample.txtを作成し、内容を保存
Creative Commons Attribution 3.0 License
85. どこまでできた?
http://localhost:8080/edit/sample
/view/sample
editHandler
Title Title
Editing sample edit.html sample viewHandler
view.html
sample body [edit]
sample body
Body Body
Save
/save/sample
sample.txtを作成し、内容を保存
Creative Commons Attribution 3.0 License
89. saveHandlerを作成
テキストエリアに
edit.htmlを次のようにします。
入力した内容(string型)を取得できる
http.StatusMovedPermanently = 301
http.HandleFunc(“/save/”, saveHandler)
http.StatusFound = 302
http.StatusSeeOther = 303
func saveHandler(w http.ResponseWriter, r *http.Request) {
title := r.URL.Path[6:] http.StatusTemporaryRedirect = 307
body := r.FormValue("body")
p := &Page{Title:title, Body:[]byte(body)}
p.save()
http.Redirect(w, r, "/view/" + title, http.StatusFound)
}
ステータスコードを付与してリダイレクトする
ここでは“/view/” + title にリダイレクト
Creative Commons Attribution 3.0 License
96. 基本的なwikiは完成
http://localhost:8080/edit/sample
/view/sample
editHandler
Title Title
Editing sample edit.html sample viewHandler
view.html
sample body [edit]
sample body
Body Body
Save
/save/sample
sample.txtを作成し、内容を保存
Creative Commons Attribution 3.0 License
97. 基本的なwikiは完成
http://localhost:8080/edit/sample
/view/sample
editHandler
Title Title
Editing sample edit.html sample viewHandler
view.html
sample body [edit]
sample body
Body saveHandler
Body
Save
/save/sample
sample.txtを作成し、内容を保存
Creative Commons Attribution 3.0 License
100. GET、POST
net/http パッケージ
func Get(url string) (resp *Response, err error)
例 res, _ := http.Get("http://www.google.com/robots.txt")
body, _ := iouti.ReadAll(res.Body)
res.Body.Close()
func Post(url string, bodyType string, body io.Reader)
(resp *Response, err error)
Creative Commons Attribution 3.0 License
101. XML、JSON
encoding/xml
パッケージが使用できます。
encoding/json
例 http://play.golang.org/p/ADbOOeCVCn
Creative Commons Attribution 3.0 License
102. XML、JSON
encoding/xml
パッケージが使用できます。
encoding/json
xml
構造体
json
例 http://play.golang.org/p/ADbOOeCVCn
Creative Commons Attribution 3.0 License
103. XML、JSON
encoding/xml
パッケージが使用できます。
encoding/json
Marshal(v interface{}) (data []byte, error)
xml
構造体
json
Unmarshal(data []byte, v interface{}) error
例 http://play.golang.org/p/ADbOOeCVCn
Creative Commons Attribution 3.0 License
104. XML、JSON
encoding/xml
パッケージが使用できます。
encoding/json
Marshal(v interface{}) (data []byte, error)
xml
構造体 同じI/F
json
Unmarshal(data []byte, v interface{}) error
例 http://play.golang.org/p/ADbOOeCVCn
Creative Commons Attribution 3.0 License
105. XML、JSON
encoding/xml
パッケージが使用できます。
encoding/json
Marshal(v interface{}) (data []byte, error)
xml
構造体 同じI/F
json
Unmarshal(data []byte, v interface{}) error
ポインタじゃないと
例 http://play.golang.org/p/ADbOOeCVCn 怒られます
Creative Commons Attribution 3.0 License
109. FastCGI
package main
import (
! "fmt"
! "net"
! "net/http"
! "net/http/fcgi"
)
func main() {
! mux := http.NewServeMux()
! mux.HandleFunc("/", index)
! l, _ := net.Listen("tcp", ":9000")
! fcgi.Serve(l, mux)
}
func index(w http.ResponseWriter, r *http.Request) {
! fmt.Fprintf(w, "hello,FastCGI!")
}
Creative Commons Attribution 3.0 License
110. FastCGI
package main
import (
! "fmt"
! "net"
! "net/http"
! "net/http/fcgi"
)
func main() {
! mux := http.NewServeMux()
! mux.HandleFunc("/", index)
! l, _ := net.Listen("tcp", ":9000")
! fcgi.Serve(l, mux)
}
func index(w http.ResponseWriter, r *http.Request) {
! fmt.Fprintf(w, "hello,FastCGI!")
}
nginx上で動きます
Creative Commons Attribution 3.0 License