SELECT文の評価順序メモ
たまに「どうだったっけ?」と忘れてしまう時があるので。
https://qiita.com/suzukito/items/edcd00e680186f2930a8 よりメモ
FROM ON JOIN WHERE GROUP BY HAVING SELECT DISTINCT ORDER BY TOP(LIMIT)
xmllintメモ
# 妥当性検証 xmllint --schema feed.xsd --noout feed.xml # 整形 xmllint --format feed.xml # インデントスペース4文字で整形 XMLLINT_INDENT=" " xmllint --format feed.xml
Goことはじめ(ファイルのRead/Write)
http://gihyo.jp/dev/feature/01/go_4beginners/0004?page=2
より学んだことメモ
package main import ( "fmt" "log" "os" ) // // ファイルの書き込み // func FileWriteFunc() { fmt.Println("ファイルの書き込み --------- ") // ファイルを生成 file, err := os.Create("./file.txt") if err != nil { log.Fatal(err) } // 終了時にファイルを閉じる defer file.Close() // 書き込むデータを[]byteで用意する message := []byte("hello world\n") // Write()を用いて書き込む _, err = file.Write(message) if err != nil { // エラー処理 log.Fatal(err) } // 直接文字列を渡す版1 // _, err = file.WriteString("hello world\n") // 直接文字列を渡す版2 // _, err = fmt.Fprint(file, "hello world\n") } // // ファイルの読み込み // func FileReadFunc() { fmt.Println("ファイルの読み込み --------- ") // ファイルを開く file, err := os.Open("./file.txt") if err != nil { // エラー処理 log.Fatal(err) } // プログラムが終わったらファイルを閉じる defer file.Close() // 12byte格納可能なスライスを用意する message := make([]byte, 12) // ファイル内のデータをスライスに読み出す // io.Reader インターフェースを使う // type Reader interface { // Read(p []byte) (n int, err error) // } _, err = file.Read(message) if err != nil { log.Fatal(err) } // ファイルの中身をすべて読み出す // ioutil.ReadAllを使えば、事前にbyte列を準備する必要はない // file, _ := os.Open("./file.txt") // message, err := ioutil.ReadAll(file) // 文字列にして表示 fmt.Print(string(message)) } func main() { FileWriteFunc() FileReadFunc() }
JSONのEncoder/Decoder経由の保存
package main import ( "fmt" "log" "os" "encoding/json" ) type Person struct { ID int `json:"id"` Name string `json:"name"` Email string `json:"-"` Age int `json:"age"` Address string `json:"address,omitempty"` memo string } // // JSONの書き出し // func JsonWriteFunc() { fmt.Println("JSONの書き出し ---------- ") person := &Person{ ID: 1, Name: "Hogeo", Email: "hogeo@example.com", Age: 20, Address: "", memo: "TestUser", } // ファイルを開く file, err := os.Create("./person.json") if err != nil { log.Fatal(err) } defer file.Close() // エンコーダの取得 encoder := json.NewEncoder(file) // JSONエンコードしたデータの書き込み // byte[]に変換しなくても直接構造体を渡せる err = encoder.Encode(person) if err != nil { log.Fatal(err) } } // // JSONの読み込み // func JsonReadFunc() { fmt.Println("JSONの読み込み ---------- ") // ファイルを開く file, err := os.Open("./person.json") if err != nil { log.Fatal(err) } defer file.Close() // データを書き込む変数 var person Person // デコーダの取得 decoder := json.NewDecoder(file) // JSONデコードしたデータの読み込み // JSONフォーマットに誤りがあればエラー // 構造体にないフィールドは無視される err = decoder.Decode(&person) if err != nil { log.Fatal(err) } // 読み出した結果の表示 fmt.Println(person) } func main() { JsonWriteFunc() JsonReadFunc() }
ioutls使うと便利
http://gihyo.jp/dev/feature/01/go_4beginners/0004?page=3
package main import ( "fmt" "io/ioutil" "log" ) // // ファイルの操作は、 // io/ioutilsパッケージを使うとより簡単にできる // func main() { hello := []byte("hello world\n") // ファイルにメッセージを書き込む // 第2引数にバイト列、第3引数にパーミッション err := ioutil.WriteFile("./file.txt", hello, 0666) if err != nil { log.Fatal(err) } // ファイルの中身を全て読みだす message, err := ioutil.ReadFile("./file.txt") if err != nil { log.Fatal(err) } fmt.Print(string(message)) }
Goことはじめ(JSONの取り扱い)
http://gihyo.jp/dev/feature/01/go_4beginners/0004 より学んだことメモ
package main import ( "fmt" "log" "encoding/json" ) // // 構造体にタグをつけることでJSON変換時の // ルールを定義することができる // 何も指定しない場合はpublicなフィールドだけ格納される // type Person struct { ID int `json:"id"` // id という名前で格納する Name string `json:"name"` Email string `json:"-"` // JSONに格納しない Age int `json:"age"` Address string `json:"address,omitempty"` // ,omitemptyで値が空なら無視 memo string } // JSONへの変換 func JsonStringifyFunc() { fmt.Println("構造体からJSONへの変換 ---------- ") person := &Person { ID: 1, Name: "Gopher", Email: "gopher@example.org", Age: 5, Address: "", memo: "golang lover", } // 構造体にデータを代入して // ポインタを渡すだけで、 // デフォルトフォーマットでJSON文字列の[]byteを生成できる b, err := json.Marshal(person) if err != nil { log.Fatal(err) } fmt.Println(string(b)) // 文字列に変換 // -> {"id":1,"name":"Gopher","age":5} } // JSONから構造体への変換 func JsonParseFunc() { fmt.Println("JSONから構造体への変換 ---------- ") var person Person b := []byte(`{"id":1,"name":"Hogeo","age":10}`) err := json.Unmarshal(b, &person) if err != nil { log.Fatal(err) } fmt.Println(person) } func main() { JsonStringifyFunc() JsonParseFunc() }
goenvインストールメモ
# インストール $ git clone https://github.com/syndbg/goenv.git ~/.goenv # ~/.bash_profile に追記 export GOENV_ROOT="$HOME/.goenv" export PATH="$GOENV_ROOT/bin:$PATH" eval "$(goenv init -)" # 反映 source ~/.bash_profile # 使えるバージョン確認 goenv install -l # 指定バージョンをインストール goenv install 1.12.3 # グローバルで使う goenv global 1.12.3 # rehashするとGOPATHが切り替わる goenv rehash echo ${GOPATH} /Users/kinosuke/go/1.12.3 # そのディレクリ以下で使う goenv local 1.12.3 # インストール済のGo一覧 goenv versions # depのインストール # ※GOPATH以下にインストールされる # npmみたいにパッケージをプロジェクトディレクトリ内にインストールできるようにするやつ go get -u github.com/golang/dep/cmd/dep # goenvの更新 cd $(goenv root) git pull
※GOPATHとは
Go言語での開発時の作業ディレクトリ。環境変数GOPATHに保存される。
明示的な指定がない場合はデフォルト設定が使われる。
> If no GOPATH is set, it is assumed to be $HOME/go on Unix systems and %USERPROFILE%\go on Windows.
Goことはじめ3
第3章 型システム―型を用いた安全なプログラミング:はじめてのGo―シンプルな言語仕様,型システム,並行処理|gihyo.jp … 技術評論社
より学んだことメモ。
package main import ( "fmt" ) // // 型の拡張 // 同じ型でも違う意味を持つもの(同じintでもIDを表すものと優先度を表すものとか)を混同しちゃうとバグになるようなときに使う。 // type ID int type Priority int func ProcessTask(id ID, priority Priority) { fmt.Println(id, priority); } func RunProcessTask() { fmt.Println("型の拡張 ---------- ") var id ID = 3 var priority Priority = 5 // typeが違うのでコンパイルエラーする // ProcessTask(priority, id) // typeが適合するのでこっちは通る ProcessTask(id, priority) } // // 構造体 // type Task struct { ID int Detail string // パッケージ外にpublicな属性は先頭大文字 done bool // パッケージ内でprivateな属性は先頭小文字 } func RunTask() { fmt.Println("構造体 ---------- ") // Task構造体の初期化 // 値を与えなかった場合はゼロ値で初期化される var task Task = Task{ ID: 1, Detail: "buy the milk", done: true, } // 定義順に値を渡すことでフィールド名を省略 // var task Task = Task{1, "buy the milk", true} fmt.Println(task.ID) fmt.Println(task.Detail) fmt.Println(task.done) } // // ポインタ型 // 引数の方を*Taskとすることでポインタを渡せる // これで参照渡しができる // func Finish(task *Task) { task.done = true } func RunFinish() { fmt.Println("ポインタ型 ---------- ") // &Taskでポインタを渡せる task := &Task{done: false} Finish(task) fmt.Println(task.done) // true } // // 構造体の初期化 // コンストラクタがないのでNew*というメソッドを作って初期化するのが通例 // func NewTask(id int, detail string) *Task { // new()メソッドは // 構造体のフィールドをすべてゼロ値で初期化して返す var task *Task = new(Task) task.ID = id task.Detail = detail return task } func RunNewTask() { fmt.Println("構造体の初期化 ---------- ") task := NewTask(1, "buy the milk") fmt.Printf("%+v\n", task) } // // 構造体にメソッドを追加する // func (task Task) String() string { // レシーバのコピーがわたされるので // ここで値を変えてもオリジナルの値は変わらない str := fmt.Sprintf("%d) %s", task.ID, task.Detail) return str } func (task *Task) Finish() { // ポインタ渡しなのでオリジナルの値が変わる task.done = true } func RunTaskFunc() { fmt.Println("構造体のメソッド追加 ---------- ") task := NewTask(1, "buy the milk") fmt.Printf("%s\n", task) task.Finish() fmt.Printf("%s\n", task.done) } // // インターフェース // // インターフェイスの定義 // 単純なインターフェースは*erという名前をつけるのが通例 type Stringer interface { String() string } // 引数にインターフェースを指定することで // 必要なメソッドを実装していると判断する func Print(stringer Stringer) { fmt.Println(stringer.String()) } // 何も定義しないインターフェースを使うと // どのような型も渡せるメソッドを作れる func Do(e interface{}) { // do something } type StringStruct struct { Text string } func (ss *StringStruct) String() string { return ss.Text; } func NewStringStruct(text string) *StringStruct { return &StringStruct{ Text: text, } } func RunInterface() { ss := NewStringStruct("インターフェース ---------- ") Print(ss) } // // 型の埋め込み // 継承の代わりになるもの // 下記ではUserをUserTaskに埋め込む例 // type User struct { FirstName string LastName string } func (u *User) FullName() string { fullname := fmt.Sprintf("%s %s", u.FirstName, u.LastName) return fullname } func NewUser(firstName, lastName string) *User { return &User{ FirstName: firstName, LastName: lastName, } } type UserTask struct { ID int Detail string done bool *User // Userを埋め込む } func NewUserTask(id int, detail, firstName, lastName string) *UserTask { task := &UserTask { ID: id, Detail: detail, done: false, User: NewUser(firstName, lastName), } return task } func RunEmbed() { fmt.Println("型の埋め込み ---------- ") task := NewUserTask(1, "buy the milk", "Jxck", "Daniel") // UserTaskにUserのフィールドが埋め込まれている fmt.Println(task.FirstName) fmt.Println(task.LastName) // UserTaskにUserのメソッドが埋め込まれている fmt.Println(task.FullName()) // UserTaskから埋め込まれたUser自体にもアクセス可能 fmt.Println(task.User) } // // 型の変換 // func CastFunc() { // キャスト var i uint8 = 3 var j uint32 = uint32(i) // uint8 -> uint32 fmt.Println(j) var s string = "abc" var b []byte = []byte(s) // string -> []bytes fmt.Println(b) // キャストに失敗した場合はパニックが発生する // a := int("a") } func TypeAssertionFunc(value interface{}) { // TypeAssertion // 第1戻り値はその型に変換された値が返り、 // 第2戻り値は成否を返す // (第2戻り値を指定しなかった場合はパニック起こる) s, ok := value.(string) if ok { fmt.Printf("value is string: %s\n", s) } else { fmt.Printf("value is not string\n") } } func TypeSwitchFunc(value interface{}) { switch v := value.(type) { case string: fmt.Printf("value is string: %s\n", v) case int: fmt.Printf("value is int: %d\n", v) case Stringer: fmt.Printf("value is Stringer: %s\n", v) } } func RunType() { fmt.Println("型の変換 ---------- ") CastFunc() TypeAssertionFunc("StringValue") TypeAssertionFunc(1) TypeSwitchFunc("StringValue!!") TypeSwitchFunc(10) } func main() { RunProcessTask() RunTask() RunFinish() RunNewTask() RunTaskFunc() RunInterface() RunEmbed() RunType() }
チャネルにバッファを設けて処理ブロックを制御
package main import ( "fmt" "time" ) func main() { // バッファを3として設定 ch := make(chan string, 3) go func() { time.Sleep(time.Second) s := <-ch // 1秒後にデータを読み出す fmt.Printf("get %s\n", s) }() ch <- "a" // ブロックしない fmt.Println("put a") ch <- "b" // ブロックしない fmt.Println("put b") ch <- "c" // ブロックしない fmt.Println("put c") ch <- "d" // 1秒後にデータが読み出されるまでブロック fmt.Println("put d") }
geminaboxにgem登録する手順メモ
# 準備 gem install geminabox --no-ri --no-doc # Gemを作る gem build -V ***.gemspec mv ***-0.1.0.gem pkg/. # アップロードする gem inabox ./pkg/***-0.1.0.gem --host http://example.com