Presented by いわーく, 上田哲広
- Googleが2009年に公開した比較的新しい言語
- シンプルで読みやすいことを重視して作られた
- 静的型付け、静的コンパイル
- コンパイル、実行速度が速い(ネイティブコンパイル)
- 標準ツールが充実(go get, go fmt, go test...)
- オープンソース
- ガベージコレクションによるメモリ管理
- 並列処理が得意
- ダックタイピングができる
- クロスコンパイル
- Google, Youtube
- Docker
- Dropbox
- GitHub
- Donuts
ホームディレクトリ以下のgocodeディレクトリを 作業ディレクトリとする場合、下記のようになる。
export GOPATH="$HOME/gocode"
export PATH="$GOPATH/bin/:$PATH"
bash_profileやzshrc等に書いておくと、 起動時に読み込まれるため、毎回打つ必要がなくなる。 Windowsの人は 「windows 環境変数 path」等でググる。
$HOME/gocode/src/hello/hello.go
package main // 実行されるパッケージ
import "fmt" // fmtパッケージを使用する
func main() { // エントリーポイント
fmt.Println("hello, world")
}
$ go run hello.go
var n int = 1 // int型の変数n
n = 2
n += 1
n := 1 // 型推論(1を代入しているのでint型であると推論される)
n *= 3
型名 | 説明 |
---|---|
uint8, uint16, uint32, uint64 | 符号なし整数(8-64bit) |
byte | uint8のalias(別名) |
int8, int16, int32, int64 | 符号あり整数(8-64bit) |
rune | int32のalias(別名)。Unicode文字の1文字を格納する型。Go言語では文字のことをルーンと呼ぶ |
float32, float64 | 浮動小数点数(32, 64bit) |
complex64, complex128 | 複素数。実数部、虚数部それぞれが32bitまたは64bit |
uint | 符号なし整数。システム環境により32bitまたは64bit |
int | 符号あり整数。システム環境により32bitまたは64bit |
uintptr | ポインタの値を格納するための符号なし整数。サイズはシステム環境による |
文字列を格納するのにはstring型を使う。
package main
import (
"fmt"
"unicode/utf8"
)
func main() {
var str string = "Donuts"
// 「+」演算子で結合可能
str = "株式会社" + str
// 文字数を出力
fmt.Println(str, "lenth:", utf8.RuneCountInString(str))
}
Go言語は型のチェックが厳しく、整数型同士でも型が違えば代入や比較ができない。 例) int32とint64
var i int = 1234
var u uint32 = uint32(i)
var f float32 = float32(u)
func add(a int, b int) int{
return a + b
}
sum := add(10, 20) // => 30
func calc(a int, b int) (int, int, int, float32){
return(
a + b,
a - b,
a * b,
float32(a) / b
)
}
sum, sub, mul, div := calc(1, 2) // => 3, -1, 2, 0.5
配列型の書式は以下の通り。
[長さ]要素型
// 配列の宣言
var array1 [8]int64
var array2 [1]byte
// 初期化(不足分はゼロ値で初期化)
array3 := [6]int{1, 2, 3, 4}
// 配列の長さ
len(array1)
if文やfor文は他の言語でよくあるものと同様。丸カッコ「()」は要らない。
「range」式を使用すると配列などの値から要素を1つずつ取り出してループできる。
if 条件式 {
// 条件式がtrueとなるとき実行されるブロック
} else {
// falseとなるとき実行されるブロック
}
for i := 0; i < 5; i++ {
// 5回繰り返されるブロック
}
for 変数 := range 配列等 {
// 配列の要素の数だけ繰り返される
}
type Person struct {
Height float32
Weight float32
}
1から100までの数値について、順番に数値を出力する。
ただし、3の倍数の場合は数値ではなく「Fizz」、5の倍数は「Buzz」、15の倍数は「Fizz Buzz」と出力する。
使うパッケージ:
- fmtパッケージ
以下のURLへHTTPでアクセスして、その結果を表示する
https://gist.githubusercontent.com/Iwark/8a294789add68b9a61fa/raw/f720b43e12539d03e2550e680b54baf8825f2db1/golang20151124.md
使うパッケージ:
- fmt
- net/http
- io/ioutil
カレントディレクトリにあるファイルの一覧を出力する。
余力がある人は、コマンド引数でディレクトリを指定できるようにする。
使うパッケージ:
- fmt
- ディレクトリの読み込み => "io/ioutil"パッケージのReadDir
- コマンド引数 => "os"パッケージのArgs
テキストファイルを読み込んで コマンド引数で指定された文字列を含む行だけを出力。 余力がある人は、正規表現にも対応する。
使うパッケージ:
- fmt
- コマンド引数, ファイルの読み込み => os
- 行ごとのファイルの読み込み(Scanner) => bufio
- 文字列の検索 => strings
- 正規表現 => regexp
以下のJSON形式のテキストをデコードして、内部の値を表示する
https://gist.githubusercontent.com/Iwark/ba6f1f73a059f7f7f675/raw/39bde97ad72096bdf23ccb027b915c5e8c71966b/golang20151124json.json
使うパッケージ:
- fmt
- net/http
- io/ioutil
- encoding/json
ローカルでHello Worldを表示するサーバー。
使うパッケージ:
- net/http
HTMLファイルを解析してaタグのリンク先(href)のみを出力する
使うパッケージ:
- go.net/html
http://www.donuts.ne.jp/
package main
import (
"fmt"
)
func main() {
for i:= 1; i <= 100; i++ {
if i % 3 == 0 && i % 5 == 0 {
fmt.Println("FizzBuzz")
} else if i % 3 == 0 {
fmt.Println("Fizz")
} else if i % 5 == 0 {
fmt.Println("Buzz")
} else {
fmt.Println(i)
}
}
}
package main
import (
"fmt"
"net/http"
"io/ioutil"
)
func main() {
url := "https://gist.githubusercontent.com/Iwark/8a294789add68b9a61fa/raw/f720b43e12539d03e2550e680b54baf8825f2db1/golang20151124.md"
res, err := http.Get(url)
if err != nil {
fmt.Println(err)
return
}
defer res.Body.Close()
if res.StatusCode != 200 {
fmt.Println(res.StatusCode)
return
}
body, err := ioutil.ReadAll(res.Body)
if err != nil {
fmt.Println(err)
return
}
fmt.Println(string(body))
}
package main
import (
"fmt"
"io/ioutil"
)
func main() {
files, err := ioutil.ReadDir("./")
if err != nil {
fmt.Println(err)
} else {
for _, f := range files {
// ディレクトリは末尾に「/」をつける
if f.IsDir() {
fmt.Println(f.Name() + "/")
} else {
fmt.Println(f.Name())
}
}
}
}
package main
import (
"bufio"
"fmt"
"os"
"regexp"
)
func main() {
filePath := os.Args[1]
grepString := os.Args[2]
regex := regexp.MustCompile(grepString)
file, err := os.Open(filePath)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
defer file.Close()
scanner := bufio.NewScanner(file)
for scanner.Scan() {
text := scanner.Text()
if regex.Match([]byte(text)) {
fmt.Println(text)
}
}
}
package main
import (
"fmt"
"net/http"
"io/ioutil"
"encoding/json"
)
func main() {
url := "https://gist.githubusercontent.com/Iwark/ba6f1f73a059f7f7f675/raw/39bde97ad72096bdf23ccb027b915c5e8c71966b/golang20151124json.json"
res, err := http.Get(url)
if err != nil {
fmt.Println(err)
return
}
defer res.Body.Close()
if res.StatusCode != 200 {
fmt.Println(res.StatusCode)
return
}
body, err := ioutil.ReadAll(res.Body)
if err != nil {
fmt.Println(err)
return
}
var data []struct {
Todo string
At string
}
json.Unmarshal(body, &data)
for _, item := range data {
fmt.Println(item.Todo + "を" + item.At + "にやる")
}
}
package main
import (
"net/http"
)
func HelloServer(w http.resWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/plain")
w.Write([]byte("Hello, World"))
}
func main() {
http.HandleFunc("/", HelloServer)
http.ListenAndServe(":8080", nil)
}
package main
import (
"fmt"
"net/http"
"golang.org/x/net/html"
"io/ioutil"
"strings"
)
func main() {
url := "https://candypot.jp/summaries/1050"
res, err := http.Get(url);
if err != nil {
fmt.Println(err)
return
}
if res.StatusCode != 200 {
fmt.Println(res.StatusCode)
return
}
body, err := ioutil.ReadAll(res.Body)
if err != nil {
fmt.Println(err)
return
}
doc, err := html.Parse(strings.NewReader(string(body)))
if err != nil {
fmt.Println(err)
return
}
var f func(*html.Node)
f = func(n *html.Node) {
if n.Type == html.ElementNode && n.Data == "a" {
// n.Attrで属性を一覧する
for _, a := range n.Attr {
if a.Key == "href" {
fmt.Println(a.Val)
}
}
}
for c := n.FirstChild; c != nil; c = c.NextSibling {
f(c)
}
}
f(doc)
}