LoginSignup
0
2

More than 3 years have passed since last update.

Golangをやっていて気になったことのメモ

Last updated at Posted at 2019-06-19

■intのサイズはアーキテクチャによる

// intのサイズはアーキテクチャによる
fmt.Println(32 << (^uint(0) >> 63)) // 64と出たら64bit

固定したい場合は、素直に int32 と書く。

■型について

  • 基本型(Bool, String, すべての数値)
  • 合成型(Struct, Array)
  • 参照型(Chan, Func, Ptr, Slice, Map, Interface{})
  • その他(reflect.Valueのゼロ値, 全く値ではないという意味の Invalid)

変数を入れ替えたり関数に渡す場合、コピーとなるため、structなどはポインタ型にしてから渡したほうが良い。

十分に小さいstructの場合は、デリファレンス(ポインタ解除)のほうがコストが高くなるため、ポインタ型にしないほうが良いらしいが、いちいち考えるのが面倒なため一律ポインタ型のほうが良いのかな?

参照型は生まれながらにポインタ型っぽい扱いなので、参照型に対してポインタ型を使う必要は無い。

Golangの配列型Array型とSlice型について

Arrayが合成型なのがやばい。配列は基本Sliceを使っていったほうが良さそう。

a := [3]int64{1, 2, 3} // array
s :=  []int64{1, 2, 3} // slice

※下記記事が詳しい
Goのarrayとsliceを理解するときがきた

■mapのキー存在チェックは、下記のように書くと速い

map1 := map[string]string{"aaa": "aaa111"}
if v, ok := map1["aaa"]; ok {
  fmt.Println(v) // pring aaa111
}

■interface{}からキャストするときにもokがある

func main() {
    type Foo struct {
    }
    var e interface{}
    e = Foo{}
    if _, ok := e.(Foo); ok {
        fmt.Println(e)
    }
}

■先頭大文字にすると公開関数や変数となる

type Foo struct {
    ID   string // public いつでも触れる
    name string // private これは定義したときか、Foo structが置かれているファイル内でしか変更できない
}

■日付フォーマットの指定がよくあるやつだとyyyy-mm-ddとかだが、yyyyを2006って書くみたい

fmt.Println(time.Now().Format("2006-01-02:15:04:05.000"))
// ↑のフォーマット指定で出力が下記。。。
// 2019-07-10:14:24:48.517 

1月2日午後3時4分5秒2006年 ね?揃っているでしょ?的な軽い気持ちだったらしい。

(せめて、午前3時なら15って書かなくて済んだのになぁ。。)

プログラミングはウケ狙いで書くと後で恥ずかしかったり、訳分からんとなるのでコメントとか気を付けよう(戒め感ある)

※参考記事
Goのtimeパッケージのリファレンスタイム(2006年1月2日)は何の日?

※余談だが、↑の記事の方はGolangのコミット権限を持っているらしい。

■Object型をinterface{}と書く

var obj interface{}
str := "str1"
obj = str

正確にはObject型じゃないらしいが、ざっくり理解としてはそれでいいはず。

■Javaとか他の言語で言うクラスが、フォルダ(package)単位

■フォルダとpackage名を合わせるのがお作法

■フォルダにファイルを複数置けるが、privateメソッドなども共有となるため、javaっぽいprivateがお望みならば、1フォルダ1ファイルとしたほうが分かりやすい。

フォルダが多くなりすぎるが、個人的には読みやすさ重視かなぁと。

■テストコードは循環参照などの問題が出ることがあるため、package名 + "_test"としたほうが良い(この状態でテストは動く)

■stringにnilが入らない。

■Goルーチンを使うなら、contextを引き継ぐと綺麗に終わらせられる

■buildしなくても動かせる

go run main.go

■go modulesに移行期(2019-06-19現在)で、Go1.13からデフォルトになる

■xerrorsパッケージも移行期(2019-06-19現在)で、Go1.13からデフォルトになる

■xhogeみたいにxパッケージ名のモジュールは、準標準パッケージ

■意外とシャドーイングが発生しやすいので気を付ける。出来るだけ別名使う?

package main

import (
    "fmt"
)

func main() {
    str := "str1"
    if true {
        str := "str2"
        // str = "str2" // '='なら外側の変数に入る
        fmt.Println(str) // str2
    }
    fmt.Println(str) // str1
}

■リフレクション処理がマジでむずかしいのでつらい

■switch文がJavaなどと違う

golangを基礎から学ぶ 制御構造編

switch-caseのデフォルト動作は fallthrough ではない

途中条件でマッチしたら、その下には行かないということ。

■nilが型を持っているのでチェックには気を付けないといけない

package main

import "fmt"

func main() {
    var x *int32 = nil

    fmt.Println(x == nil) // true

    isnil(x)

    isnil2(x)
}

func isnil(x interface{}) {
    fmt.Println(x == nil) // false
}
func isnil2(x *int32) {
    fmt.Println(x == nil) // true
}

play groundで試せます

下記のようなコードなら判定できそうだが。。
https://github.com/gotestyourself/gotest.tools/blob/v3.0.0/assert/cmp/compare.go#L268

■特定行でスタックトレースを強制的に出したい(標準エラーに出力される?)

package main

import "runtime/debug"

func main() {
    debug.PrintStack()
}

最後に


この記事はどんどん追記していきますm(_ _)m

0
2
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2