LoginSignup
0
0

More than 3 years have passed since last update.

Golang勉強メモ 雑記

Posted at

golangを動かして思ったことを雑多にメモする
大きくなりそうなものは別途記事としてまとめる

静的解析が便利(らしい)

静的解析とは

コードを実行せずにきれいにしてくれるマン
golang自体がシンプルなコードで、静的解析のしやすさを目指しているらしく
静的解析との相性がいいらしい。
https://golang.org/doc/faq#change_from_c

Second, the language has been designed to be easy to analyze and can be parsed without a symbol table.

fmt

公式から提供されているフォーマッタ。
ファイル保存のタイミングで、自動的にソースのフォーマットを行ってくれる。
実施してくれるのは

  • 行間のフォーマット
  • 変数、型のインデント揃え
  • 不要(ソース内未使用)パッケージの削除
  • 制御構文の()削除※ ※golangはif,switch,forの制御構文に()は利用しない

など
ezgif-3-89c5e65aac7a.gif

fmtやgoのフォーマットに関する詳しい情報はこちら
Command gofmt
Effective Go

使おうと思っている自作のパッケージをimportに書いて、
コード内で使用せずに保存すると消えてしまうのでちょっと悲しい。

lint

コードの改良案を提案してくれる。
image.png
おおまかな提案内容は以下の通り

  • 構造体へのコメント付与
  • パブリック関数へのコメント付与

vet

デッドコードの検出をしてくれる。
デフォルトじゃ入っていない気がする。
未着手。

packageの扱い

とりあえず色々ソースを作って動かそうと思ってこんなディレクトリ構成にしてる。
gogo.goは疎通確認、person.goは構造体のテストで
お互い独立したソースファイルである。

golang
├gogo.go
└person.go

goは

  • 少なくとも1つのpackageに所属する必要がある
  • コンパイル→実行時にpackage mainmain関数を実行する

ので上記両ファイルともpackage mainに所属させ、main関数を作成すると
修飾子が重複していると注意されてしまう。
image.png

go run person.goのようにファイル名を指定して実行すると
一応実行はできるのだが、ちょっと気持ちわるい。
パッケージへの所属が必須の言語ではどう整理するのが正解なのか。

一旦は作りたいソースごとにパッケージにわけ、
main.goでソースを呼び出す形に変更することに。

golang
├main.go
├hello
│└gogo.go
└person
 └person.go
package main
import "./person"
import "fmt"

func main() {
    fmt.Println("start")
    person.score()

}
package person

import (
    "fmt"
)

// Person はテストの点数管理の構造体です。
type Person struct {
    name    string
    english int
}

func score() {
    bob := Person{"Bob", 60}
    fmt.Println(bob.name, bob.english)

    if bob.english > 60 {
        fmt.Println("OK")
    } else {
        fmt.Println("NG")
    }
}

これでmain.goから自作のpackage personを読み込めると思ったのだが、
参照できず、import文から削除される・・・

原因を調査したところ、golangでは
メソッド名が小文字の場合、package外に非公開(private)、
メソッド名が大文字の場合、package外に公開(public)という設定になるらしい。
公式ドキュメントだとこのあたり?

If you have a field called owner (lower case, unexported), the getter method should be called Owner (upper case, exported), not GetOwner. The use of upper-case names for export provides the hook to discriminate the field from the method.

下記の通りメソッド名を大文字にしたところ実行できた。
小文字でも自コード内での参照はできるため、エラーにならず
原因解明に時間がかかった。

package main

import (
    "fmt"

    "./person"
)

func main() {
    fmt.Println("start")
    person.Score()

}

package person

import (
    "fmt"
)

// Person はテストの点数管理の構造体です。
type Person struct {
    name    string
    english int
}

// Score 評価のためのメソッド
func Score() {
    bob := Person{"Bob", 60}
    fmt.Println(bob.name, bob.english)

    if bob.english > 60 {
        fmt.Println("OK")
    } else {
        fmt.Println("NG")
    }
}

go run main.go
start
Bob 60
NG

参考ドキュメント

0
0
0

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
0