关于golang:Go116-新特性一文快速上手-Go-embed

41次阅读

共计 2186 个字符,预计需要花费 6 分钟才能阅读完成。

若有任何问题或倡议,欢送及时交换和碰撞。我的公众号是【脑子进煎鱼了】,GitHub 地址:https://github.com/eddycjy。

大家好,我是煎鱼。

在以前,很多从其余语言转过来 Go 语言的同学会问到,或是踩到一个坑。就是认为 Go 语言所打包的二进制文件中会蕴含配置文件的联同编译和打包。

后果往往一把二进制文件挪来挪去,就无奈把利用程序运行起来了。因为无奈读取到动态文件的资源。

无奈将动态资源编译打包进二进制文件的话,通常会有两种解决办法:

  • 第一种是辨认这类动态资源,是否须要跟着程序走。
  • 第二种就是思考将其打包进二进制文件中。

第二种状况的话,Go 以前是不反对的,大家就会去借助各种花式的开源库,例如:go-bindata/go-bindata 来实现。

但从在 Go1.16 起,Go 语言本身正式反对了该项个性,明天咱们将通过这篇文章疾速理解和学习这项个性。

根本应用

演示代码:

import _ "embed"

//go:embed hello.txt
var s string

func main() {print(s)
}

咱们首先在对应的目录下创立了 hello.txt 文件,并且写入文本内容“吃煎鱼”。

在代码中编写了最为外围的 //go:embed hello.txt 注解。注解的格局很简略,就是 go:embed 指令申明,外加读取的内容的地址,可反对绝对和绝对路径。

输入后果:

吃煎鱼

读取到动态文件中的内容后主动赋值给了变量 s,并且在主函数中胜利输入。

而针对其余的根底类型,Go embed 也是反对的:

//go:embed hello.txt
var s string

//go:embed hello.txt
var b []byte

//go:embed hello.txt
var f embed.FS

func main() {print(s)
    print(string(b))

    data, _ := f.ReadFile("hello.txt")
    print(string(data))
}

输入后果:

吃煎鱼
吃煎鱼
吃煎鱼

咱们同时在一个代码文件中进行了多个 embed 的注解申明。

并且针对 string、slice、byte、fs 等多种类型进行了打包,也不须要过多的解决,十分便当。

拓展用法

除去根本用法完,embed 自身在指令上也反对多种变形:

//go:embed hello1.txt hello2.txt
var f embed.FS

func main() {data1, _ := f.ReadFile("hello1.txt")
    fmt.Println(string(data1))

    data2, _ := f.ReadFile("hello2.txt")
    fmt.Println(string(data2))
}

在指定 go:embed 注解时能够一次性多个文件来读取,并且也能够一个变量多行注解:

//go:embed hello1.txt 
//go:embed hello2.txt
var f embed.FS

也能够通过在注解中指定目录 helloworld,再对应读取文件:

//go:embed helloworld
var f embed.FS

func main() {data1, _ := f.ReadFile("helloworld/hello1.txt")
    fmt.Println(string(data1))

    data2, _ := f.ReadFile("helloworld/hello2.txt")
    fmt.Println(string(data2))
}

同时既然可能反对目录读取,也能反对贪心模式的匹配:

//go:embed helloworld/*
var f embed.FS

可能会有小伙伴留神到,embed.FS 也能调各类文件系统的接口,其实实质是 embed.FS 实现了 io/fs 接口。

只读属性

在 embed 所提供的 FS 中,咱们能够发现其都是关上和只读办法:

type FS
    func (f FS) Open(name string) (fs.File, error)
    func (f FS) ReadDir(name string) ([]fs.DirEntry, error)
    func (f FS) ReadFile(name string) ([]byte, error)

依据此也能够确定 embed 所打包进二进制文件的内容只容许读取,不容许变更。

更形象来讲就是在编译期就确定了 embed 的内容,在运行时不容许批改,保障了一致性。

总结

通过 Go1.16 正式提供的 embed 个性,能够实现原生就反对动态资源文件的嵌入。整体如下:

  • 在性能上:可能将动态资源嵌入二进制文件中,在运行时能够关上和读取相干的打包后的动态文件。
  • 在平安上:是在编译期编译嵌入,在运行时不反对批改。
  • 在应用上:

    • 反对单文件读取:go:embed hello.txt
    • 反对多文件读取:go:embed hello1.txtgo:embed hello2.txt
    • 反对目录读取:go:embed helloworld
    • 反对贪心匹配:go:embed helloworld/*

总的来讲,Go1.16 embed 个性很好的填补了 Go 语言在打包动态文件资源的一块原生空白畛域。同时也阐明了 Go 官网确实在一直地排汇社区的一些良好的想法和教训。

我的公众号

分享 Go 语言、微服务架构和奇怪的零碎设计,欢送大家关注我的公众号和我进行交换和沟通。

最好的关系是相互成就 ,各位的 点赞 就是煎鱼创作的最大能源,感激反对。

正文完
 0