-
Notifications
You must be signed in to change notification settings - Fork 0
golang tips
foolmacky edited this page Sep 11, 2021
·
10 revisions
- interface{}は実体は型情報と、データの実体or実体へのポインタの2つの値しか持っていない
- 値が入るのか、ポインタが入るのかは、実体データの型によって異なる
intならデータが入る。structは実体へのポインタが格納される
なので、deep copyしてもあまり気にしなくても大丈夫
- interface{}のポインタにはinterface{}としての機能が「無い」ため、デリファレンスする必要がある
package main
import log
type Person struct {
Name string
}
func main() {
p := Person{Name: "hoge"}
iftest(p)
iftestNull(nil)
iftestNull()
}
//interface{}のタイプassertionはstructに関しても有効
func iftest(param interface{} {
log.Println(param.(Person).Name)
}
func iftestNull(param interface{}) {
if param == nil {
log.Println("This is NULL")
}
}
- 異なるパッケージのインターフェースも満たすことができる
- Interfaceを満たしている関数のリスナーをポインタ型にすると、そのStructのポインター変数しかインターフェースを満たさない。実体の変数はInterfaceを満たさない。
- リスナーを実体にしていれば、両方満たす。
package main
import log
type PSample struct {
name string
}
type Sample struct {
name string
}
type AllStruct interface {
Exec()
}
func (psample *PSample) Exec() {
log.Println(psample.name)
}
//func (psample PSample) Exec() {
//log.Println(psample.name)
//}
//同じ関数定義を、ポインターと実体の両方で定義することはできない
func main() {
psample := &Psample{name: "psample"}
sample := Sample{name: "sample"}
var allstructs = []AllStruct{psample, sample}
for _, sam := range allstructs {
sam.Exec()
}
psample2 := Psample{name: "psample2"}
//実体を一度ポインタ変数に代入すれば、インターフェースを満たすことができる
var ppsample2 = &psample2
sample3 := &Sample{name: "psample3"}
//実体の場合はポインタ変数にしても「当然」インターフェースを満たすことができる
var allstrct2 = []AllStruct{psample, sample, ppsample2, sample3}
for _, sam2 := range allstruct2 {
sam2.Exec()
}
}
- Goでstruct以外の型のポインターを取得するプログラムは、だいたい全部間違っている https://qiita.com/ruiu/items/e60aa707e16f8f6dccd8
https://www.slideshare.net/takuyaueda967/go-77689475
正規バージョンではなく、特定のコミットを使いたい場合の指定について
- 特定のコミット指定をgo.modに記入するのは面倒くさい。その場合はgo getでコミットhashタグを指定して取得するとgo.modを自動で更新してくれる
go get \<リポジトリ\>@\<hashタグ\>
- versionタグを付与していないパッケージの場合 go.modの記載ver.は通常v0.0.0-TIMESTAMP-hashだが、途中までver.タグが付与されていると必ずしもそうではない。go getしてgoに書き換えてもらうのが良い。
- 利用しているライブラリがリポジトリ移動した場合のエラー
module declared its path as < new repository>
but was requires as < old repository>
- 参照しているソース自体、タグを含めて新しいリポジトリに移動していたとしても、そのタグが保持しているgo.modに古いリポジトリが設定されているとこのエラーが出る
- 使うバージョンをgo.modも新しいリポジトリを指しているものに更新する