是否可以在go中包含外部文件作为字符串常量?

时间:2013-12-28 14:00:49

标签: string import include go constants

我一直希望可以在C ++中做这样的事情:

const std::string fragmentShader = "
#include "shader.frag"
";

显然这不起作用,并且没有办法在C ++中实现。但它有可能去吗?即。

const fragmentShader string = `
<insert contents of shader.frag at compile-time>
`

动机应该是显而易见的!

2 个答案:

答案 0 :(得分:2)

不是,但这里有几个选项:

  1. 只需获取文件的内容并将其放入源代码中:

    const fragmentShaderFile = `contents of shader.frag`
    
  2. 您可以使用此工具嵌入资源:https://github.com/jteeuwen/go-bindata,但您必须在文件发生更改时重新嵌入该文件。 (人们可以将其自动化为git pre-commit hook但是)

答案 1 :(得分:1)

这在纯Go中是不可能的。但是,您可以编写一个程序来读取文件并从中创建一个Go文件,例如:

package main

import "flag"
import "os"
import "fmt"
import "bufio"
import "io"

var (
    packageName = flag.String("p", "main", "package name")
    outFile     = flag.String("o", "-", "output file. Defaults to stdout")
    varName     = flag.String("v", "file", "variable name")
)

const (
    header  = "package %s\n\nvar %s = [...]byte{\n"
    trailer = "}\n"
)

func main() {

    flag.Parse()

    if len(flag.Args()) != 1 {
        fmt.Fprintln(os.Stderr, "Please provide exactly one file name")
        os.Exit(1)
    }

    var inF, outF *os.File

    if *outFile == "-" {
        outF = os.Stdout
    } else {
        var err error
        outF, err = os.Create(*outFile)
        if err != nil {
            fmt.Fprintf(os.Stderr, "Cannot create %s: %v\n", *outFile, err)
            os.Exit(1)
        }
    }

    inF, err := os.Open(flag.Args()[0])
    if err != nil {
        fmt.Fprintf(os.Stderr, "Cannot open %s: %v\n", flag.Args()[0], err)
        os.Exit(1)
    }

    in, out := bufio.NewReader(inF), bufio.NewWriter(outF)

    fmt.Fprintf(out, header, *packageName, *varName)

    buf := make([]byte, 16)

    var n int

    for n, err = io.ReadFull(in, buf); n > 0; n, err = io.ReadFull(in, buf) {
        out.WriteRune('\t')

        for i := 0; i < n-1; i++ {
            fmt.Fprintf(out, "%#02x, ", buf[i])
        }

        fmt.Fprintf(out, "%#02x,\n", buf[n-1])
    }

    out.WriteString(trailer)

    out.Flush()

    if err != io.EOF {
        fmt.Fprintf(os.Stderr, "An error occured while reading from %s: %v\n", flag.Args()[0], err)
        os.Exit(1)
    }
}