20220117のGoに関する記事は3件です。

golangのinterface

interface がよくわからん interface を英和辞典で調べると境界面、接点、共通の問題と出てくる。 コンピューター用語辞典によると インタフェースは,実装についての情報をもたないメソッドの集合の宣言とする. インタフェース及び継承をサポートするオブジェクトシステムでは, インタフェースは,一般に他のインタフェースから継承できる ここからはコードを用いて go のコードを使いながら interface の理解を進める。 interface のメソッドを満たしていれば異なる構造体でも interface に代入できる。 1 main.go type Hoge interface { FuncA() FuncB() } type Foo struct { x string y int z bool } 上記のコードの Hoge インターフェイスは FuncA、FuncB という関数を持った集合体 = メソッドの集合体 実装部分は Foo が担っている。 実装:Foo インターフェイス:Hoge まず初めに実装部分の Foo にメソッドを定義する main.go func (f *Foo) FuncA() {} func (f *Foo) FuncB() {} Hoge インターフェイスが持っているメソッドと同じ名前のメソッドを構造体 Foo に実装する。 ここで Hoge と Foo の関係が生まれる。 ここからインターフェイスがどういう役割を果たすかを考えていく。 main.go package main type Hoge interface { FuncA() FuncB() } type Foo struct { x string y int z bool } func (f *Foo) FuncA() {} func (f *Foo) FuncB() {} func hogehoge(d Hoge) { d.FuncA() d.FuncB() } func main() { var hoge Hoge hoge = &Foo{} // 型はHoge hogehoge(hoge) foo := &Foo{} // 型はFoo hogehoge(foo) } hogehoge という新しい関数を追加した。hogehoge は引数に型 Hoge を受け取る。 main 関数に hoge と foo 二つの変数を用意し関数 hogehoge の引数に入れる。 ここで注目してほしいのが、変数 hoge と変数 foo はそれぞれ異なる型を持った変数であるが、 どちらもエラーは起きない。ここでもうひとつ新しい構造体を追加する。 main.go package main type Hoge interface { FuncA() FuncB() } // foo struct // foo method type HogeFoo struct { a string b string c string } func (h *HogeFoo) FuncA() {} func (h *HogeFoo) FuncB() {} func hogehoge(d Hoge) { d.FuncA() d.FuncB() } func main() { var hoge Hoge hoge = &Foo{} hogehoge(hoge) foo := &Foo{} hogehoge(foo) hogefoo := &HogeFoo{} hogehoge(hogefoo) } 新しく追加した構造体 HogeFoo を持った変数 hogefoo も関数 hogehoge の引数に正しく入っている。 エラーは起きない。つまり、異なる構造体を持っている変数でもひとつの interface を満たしていれば、どちらも同じ interface に代入できる。 構造体の実装と構造体の使用を切り離して考えられる。 最初に新しい interface を追加する。 main.go package main // Hoge interface type Half interface { FuncA() } // foo struct // foo method // HogeFoo struct // HogeFoo method func hogehoge(d Hoge) { d.FuncA() d.FuncB() } func half(ho Half) { ho.FuncA() } func main() { var hoge Hoge hoge = &Foo{} hogehoge(hoge) foo := &Foo{} half(foo) hogefoo := &HogeFoo{} half(hogefoo) } 新しく追加した interface、Half は FuncA だけ持っていて FuncB は持っていない。 構造体 Foo と構造体 HogeFoo は Hoge インターフェイスと Half インターフェイス、どちらも満たしている。 関数 half は Half の型を持った引数を受け取るがこの時引数に変数 foo、変数 hogefoo をそれぞれ入れると FuncA しか使用できなくなっている。 Half インターフェイスは FuncA しか持っていないので当然なのだが、これが interface を使用する有用性なのではないかと推測する。 つまり構造体の使用方法を interface によって明確にでき、構造体にさまざまなメソッドが実装されていたとしても、使用するときには必要なメソッドのみを指定し、使用できるので、不要なメソッドに依存せずに済む。 終わりに まだ実際に開発などで使用していないので確実に掴めた感覚にはなりませんでしたが、 何となくでも使い方のイメージが掴めました。 この記事が誰かの参考になると嬉しいです。 最後まで読んでいただきありがとうございました。 参考サイト Golang インターフェース [Golang]interface は何者だ-Gopher への道 ②
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Gorm✕firestoreで構造体の大文字が変換されない対処法】

Gormからfirestoreにデータを保存する際、タグをつけなければ構造体の大文字のままキーが設定されてしまったので、対処法を記述する。 単純に、firestore:"name" のようなタグを構造体に付与すればいい。 type User struct { Name string `json:"name" firestore:"name"` Email string `json:"email" firestore:"email"` } ドキュメントしっかり読もう。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

BudouX を Go と Rust で使えるようにした

少し前に BudouX というライブラリが公開されました。 日本語の文章を与えると適切な改行位置を推測してくれるライブラリで、 Python と JavaScript に対応しています。 これを Go で使いたい! と、思って移植しました。 ついでに Rust にも移植しました。 この記事では移植したライブラリについて軽く紹介したいと思います。 (使い方とかは README を読んだほうが早いかもしれません) 本家 BudouX の中身 オリジナルの BudouX は次の要素で構成されています。 機械学習モデルを訓練するための Python スクリプト JSON 形式の学習済み機械学習モデル (約 10 KB) 機械学習モデルを使用した予測処理の Python 実装 機械学習モデルを使用した予測処理の TypeScript 実装 (Web component を含む) BudouX の機械学習モデルは次の情報を feature として使用しています。 過去の予測結果 対象付近にある文字 対象付近にある文字の UNICODE ブロック 他の feature の組み合わせ JSON 形式の学習済み機械学習モデルには feature をキー、スコアを値にした連想配列が格納されており、予測処理では入力を feature に変換してスコアの合計を算出、閾値を超えたところを区切りとみなしています。 予測処理は外部ライブラリに依存していません。 つまり BudouX と同じように feature に変換してスコアの合計を算出できれば他言語でも動くことになります。 Go への移植 (BudouX-Go) デモページ Go Playground 本家由来の機械学習モデルを同梱しており次のようなコードですぐに利用可能です。 (本家は HTML の入出力をサポートしていますが BudouX-Go はプレーンテキストのみをサポートしています) model := models.DefaultJapaneseModel() words := budoux.Parse(model, "これはテストです。") fmt.Printf("%q", words) // Output: // ["これは" "テストです。"] Go への移植版である BudouX-Go は本家 BudouX から次の JSON ファイルを取得して UNICODE のブロック情報と学習済みモデルの Go コードを生成しています。 budoux/unicode_blocks.json budoux/models/ja-knbc.json 取得とコード生成処理は gen/generate.go に実装されています。 (エラー処理の問題があり Go 1.13 未満では動かないようにしています) 本体は Go 1.11 の標準パッケージのみで動くようになっており GAE/Go 1.11 に魂を縛られている同志 1 も安心してご利用いただけます。 デモページは go-app を使用した wasm で動いています。 (go-app は Go 1.17 以降が必要なため go.mod を用意して別モジュールに分離しています) Rust への移植 (BudouX-rs) デモページ 本家由来の機械学習モデルを同梱しており次のようなコードですぐに利用可能です。 (本家は HTML の入出力をサポートしていますが BudouX-rs はプレーンテキストのみをサポートしています) let model = budoux::models::default_japanese_model(); let words = budoux::parse(model, "これはテストです。"); assert_eq!(words, vec!["これは", "テストです。"]) Rust への移植である BudouX-rs は BudouX-Go をベースに開発しました。 実は Rust を書くのが初めてなので変なところがあるかもしれません。 BudouX-Go と同様に本家 BudouX から JSON ファイルを取得して UNICODE のブロック情報と学習済みモデルの Rust コードを生成しています。 取得とコード生成処理は Go (gen/generate.go) で実装されており、生成されたコードは rustfmt で整形しています。 本体はできる限り依存をなくしたかったのですが機械学習モデルをスタティックな領域に保持するため once_cell を使用しています。 デモページは Yew を使用した wasm で動いています。 (Cargo.toml のワークスペース機能で別クレートに分離しています) 他言語への移植 Swift に移植した方がいるようです。 その他 本家は HTML の入出力をサポートしていますが移植版は次の理由でプレーンテキストしかサポートしていません。 依存関係を最小にしたかった HTML の処理は外部 (フレームワーク) に任せた方がよいと思った また、同梱している本家由来のモデルは日本語で学習されているため英語をうまく処理できないようです。(元の用途的に空白で区切られている英語をさらに分割する必要がないからかもしれません) 用途によってはカスタムモデルを用意するか後処理を追加したほうがいいかもしれません。 https://cloud.google.com/appengine/docs/standard/go/go-differences ↩
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む