いろいろ備忘録日記

主に .NET とか Go とか Flutter とか Python絡みのメモを公開しています。

Goメモ-144 (embed メモ (単独ファイル, 文字列で取得))

概要

Go 1.16 から追加となった embed パッケージについてのメモ1個目。

embed パッケージは、ビルドモジュールにファイルを埋め込むことができるようになるパッケージです。

これからは外部ライブラリを利用せずにテンプレートファイルとかを埋め込んでシングルバイナリに出来たりするので個人的にとても嬉しいです。

embed パッケージのドキュメントは以下。

golang.org

使い方としては

  • 埋め込んだファイルのデータを文字列で利用
  • 埋め込んだファイルのデータをバイナリで利用
  • 埋め込んだファイルのデータをembed.FSで利用

のパターンで分かれます。最初の2つは単独ファイルの埋め込み時に適していて、3つ目は複数のファイルを埋め込んだり、ディレクトリまるごと埋め込んだりした場合に利用できます。

どうやって使うのかは、コード見たほうが多分理解しやすいです。

サンプル

以下のサンプルでは、同一ディレクトリに配置されている helloworld.txt を埋め込んで利用しています。

helloworld.txt というファイルは以下の内容です。

hello
world

んで、利用する側は以下のような感じ。

package embeds

import (
    _ "embed" // Go1.16 の embed パッケージを利用するために必要な import

    "github.com/devlights/gomy/output"
)

//go:embed helloworld.txt
var s string // helloworld.txt の中身が string として設定される

// EmbedString は、embed パッケージの機能を確認するサンプルです (文字列として値を取得)
func EmbedString() error {
    //
    // go:embed で指定されている部分は、コンパイル時に埋め込みが施される
    // なので、プログラム実行時には既に値は変数に設定済みとなっている.
    //
    output.Stdoutl("[helloworld.txt]", s)
    return nil
}

単独ファイルを string もしくは []byte で利用する場合、embedパッケージはコメント部分でしか利用されないので import の部分を

import _ "embed"

という形で指定します。

実行すると以下のようになります。

gitpod /workspace/try-golang $ make run

go get -d ./...
go run -race github.com/devlights/try-golang/cmd/trygolang -onetime -example ""

ENTER EXAMPLE NAME: embed_string
[Name] "embed_string"

[helloworld.txt]     hello
world


[Elapsed] 30.105µs

埋め込みを指示している //go:embed helloworld.txt の部分がちゃんと動作していますね。実行時には当然 helloworld.txt は必要ありません。

注意点として、バイナリにはそのまま埋め込まれていますので、バイナリエディタとかで除くと当然丸見えです。センシティブなデータは埋め込まないようにしましょう。(しないと思いますが)

参考資料

golang.org


過去の記事については、以下のページからご参照下さい。

  • いろいろ備忘録日記まとめ

devlights.github.io

サンプルコードは、以下の場所で公開しています。

  • いろいろ備忘録日記サンプルソース置き場

github.com

github.com

github.com