英文:
Is it possible to include an external file as a string constant in go?
问题
我一直希望在C++中能够像这样做:
const std::string fragmentShader = "
#include \"shader.frag\"
";
显然这是行不通的,在C++中没有办法这样做。但是在Go语言中是可能的,例如:
const fragmentShader string = `
<在编译时插入shader.frag的内容>
`
动机应该是显而易见的!
英文:
I always wished it was possible to do something like this in C++:
const std::string fragmentShader = "
#include "shader.frag"
";
Obviously that doesn't work, and there is no way to do it in C++. But it is possible in go? i.e.
const fragmentShader string = `
<insert contents of shader.frag at compile-time>
`
The motivation should be obvious!
答案1
得分: 3
不是真的,但是这里有几个选项:
-
只需将文件的内容放入你的源代码中:
const fragmentShaderFile = `shader.frag的内容`
-
你可以使用这个工具嵌入资源:https://github.com/jteeuwen/go-bindata,但是每次文件更改后都需要重新嵌入它。(可以将其自动化为git的pre-commit hook)
英文:
Not really, but here are a couple options:
-
Just take the contents of the file and put them in your source code:
const fragmentShaderFile = `contents of shader.frag`
-
You can embed assets with this tool: https://github.com/jteeuwen/go-bindata, but you'll have to re-embed the file anytime it's changed. (One could automate this as a git pre-commit hook though)
答案2
得分: 3
这是不可能在纯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)
}
}
现在已经支持这个功能了。你可以使用embed机制,如我在另一个回答中所解释的。
英文:
<s>This is not possible in pure Go.</s>¹ You could however write a program that reads a file and creates a Go file from it, such as this:
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)
}
}
¹ This is now supported. You can use the embed mechanism as explained in my other answer.
答案3
得分: 0
这些天,你应该使用embed机制。对于你的用例,可以这样做:
import _ "embed"
//go:embed shader.frag
var fragmentShader string
英文:
These days, you should probably use the embed mechanism. For your use case, that would be like
import _ "embed"
//go:embed shader.frag
var fragmentShader string
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论