diff --git a/PROGRESS.md b/PROGRESS.md index fc139ab4..154c9905 100644 --- a/PROGRESS.md +++ b/PROGRESS.md @@ -73,11 +73,13 @@ - [x] File Paths->文件路径 - [x] Directories->目录 - [x] Temporary Files and Directories->临时文件和目录 +- [x] Embed Directive->嵌入的指令 - [x] Testing and Benchmarking->单元测试和基准测试 - [x] Command-Line Arguments->命令行参数 - [x] Command-Line Flags->命令行标志 - [x] Command-Line Subcommands->命令行子命令 - [x] Environment Variables->环境变量 +- [x] Logging->日志 - [x] HTTP Clients->HTTP 客户端 - [x] HTTP Servers->HTTP 服务端 - [x] Context diff --git a/examples.txt b/examples.txt index 2ef0ce00..b051fcee 100644 --- a/examples.txt +++ b/examples.txt @@ -65,11 +65,13 @@ Line Filters->行过滤器 File Paths->文件路径 Directories->目录 Temporary Files and Directories->临时文件和目录 +Embed Directive->嵌入的指令 Testing and Benchmarking->单元测试和基准测试 Command-Line Arguments->命令行参数 Command-Line Flags->命令行标志 Command-Line Subcommands->命令行子命令 Environment Variables->环境变量 +Logging->日志 HTTP Clients->HTTP 客户端 HTTP Servers->HTTP 服务端 Context diff --git a/examples/embed-directive/embed-directive.go b/examples/embed-directive/embed-directive.go new file mode 100644 index 00000000..958500c4 --- /dev/null +++ b/examples/embed-directive/embed-directive.go @@ -0,0 +1,41 @@ +// `//go:embed` 是一个 [编译器指令](https://pkg.go.dev/cmd/compile#hdr-Compiler_Directives), +// 它允许程序在构建时将任意文件和文件夹包含在 Go 二进制文件中。在这里阅读有关嵌入指令的更多信息:[这里](https://pkg.go.dev/embed)。 +package main + +// 导入 `embed` 包;如果您不使用该包中的任何导出标识符,可以使用 `_ "embed"` 进行空白导入。 +import ( + "embed" +) + +// `embed` 指令接受相对于包含 Go 源文件的目录的路径。 +// 该指令将文件的内容嵌入到紧随其后的 `string` 变量中。 +// +//go:embed folder/single_file.txt +var fileString string + +// 将文件的内容嵌入到一个 `[]byte` 中。 +// +//go:embed folder/single_file.txt +var fileByte []byte + +// 我们还可以使用通配符嵌入多个文件甚至文件夹。 +// 这将使用 [embed.FS 类型](https://pkg.go.dev/embed#FS)的变量, +// 该类型实现了一个简单的虚拟文件系统。 +// +//go:embed folder/single_file.txt +//go:embed folder/*.hash +var folder embed.FS + +func main() { + + // 打印出 `single_file.txt` 的内容。 + print(fileString) + print(string(fileByte)) + + // 从嵌入的文件夹中检索一些文件。 + content1, _ := folder.ReadFile("folder/file1.hash") + print(string(content1)) + + content2, _ := folder.ReadFile("folder/file2.hash") + print(string(content2)) +} diff --git a/examples/embed-directive/embed-directive.hash b/examples/embed-directive/embed-directive.hash new file mode 100644 index 00000000..f81e3174 --- /dev/null +++ b/examples/embed-directive/embed-directive.hash @@ -0,0 +1,2 @@ +69526bd78ac861c85bb12b96e9f1273e8aecc5a6 +6m2ll-D52BB diff --git a/examples/embed-directive/embed-directive.sh b/examples/embed-directive/embed-directive.sh new file mode 100644 index 00000000..eb6998b9 --- /dev/null +++ b/examples/embed-directive/embed-directive.sh @@ -0,0 +1,13 @@ +# 使用这些命令来运行示例。 +#(注意:由于 Go Playground 的限制,这个示例只能在您的本地机器上运行。) +$ mkdir -p folder +$ echo "hello go" > folder/single_file.txt +$ echo "123" > folder/file1.hash +$ echo "456" > folder/file2.hash + +$ go run embed-directive.go +hello go +hello go +123 +456 + diff --git a/examples/embed-directive/folder/file1.hash b/examples/embed-directive/folder/file1.hash new file mode 100644 index 00000000..190a1803 --- /dev/null +++ b/examples/embed-directive/folder/file1.hash @@ -0,0 +1 @@ +123 diff --git a/examples/embed-directive/folder/file2.hash b/examples/embed-directive/folder/file2.hash new file mode 100644 index 00000000..8d38505c --- /dev/null +++ b/examples/embed-directive/folder/file2.hash @@ -0,0 +1 @@ +456 diff --git a/examples/embed-directive/folder/single_file.txt b/examples/embed-directive/folder/single_file.txt new file mode 100644 index 00000000..606d5970 --- /dev/null +++ b/examples/embed-directive/folder/single_file.txt @@ -0,0 +1 @@ +hello go diff --git a/examples/logging/logging.go b/examples/logging/logging.go new file mode 100644 index 00000000..65782c1b --- /dev/null +++ b/examples/logging/logging.go @@ -0,0 +1,60 @@ +// Go标准库提供了直观的工具用于从Go程序输出日志 +// 使用 [log](https://pkg.go.dev/log) 包进行自由格式输出 +// 使用 [log/slog](https://pkg.go.dev/log/slog) 包进行结构化输出。 + +package main + +import ( + "bytes" + "fmt" + "log" + "os" + + "log/slog" +) + +func main() { + + // 只需调用 `log` 包中的 `Println` 等函数即可使用 _标准_ logger。 + // 它已经预先配置为将日志输出到 `os.Stderr`。 + // 像 `Fatal*` 或 `Panic*` 这样的附加方法将在记录日志后退出程序。 + log.Println("standard logger") + + // 日志记录器可以使用 _flags_ 进行配置,以设置它们的输出格式。 + // 默认情况下,标准记录器已设置了 `log.Ldate` 和 `log.Ltime` 标志, + // 并将它们收集在 `log.LstdFlags` 中。 + // 我们可以更改其标志以发出微秒精度的时间,例如: + log.SetFlags(log.LstdFlags | log.Lmicroseconds) + log.Println("with micro") + + // 它还支持发出调用 log` 函数的文件名和行号。 + log.SetFlags(log.LstdFlags | log.Lshortfile) + log.Println("with file/line") + + // 可能会有用创建一个自定义记录器并在各处传递它。 + // 创建新记录器时,我们可以设置一个 _前缀_ 来区分其输出和其他日志记录器。 + mylog := log.New(os.Stdout, "my:", log.LstdFlags) + mylog.Println("from mylog") + + // 我们可以使用 `SetPrefix` 方法在现有的记录器(包括标准记录器)上设置前缀。 + mylog.SetPrefix("ohmy:") + mylog.Println("from mylog") + + // 日志记录器可以具有自定义的输出目标;任何 `io.Writer` 都可以使用。 + var buf bytes.Buffer + buflog := log.New(&buf, "buf:", log.LstdFlags) + + // 这个调用将日志输出写入到 `buf` 中. + buflog.Println("hello") + + // 这将实际上显示在标准输出上。 + fmt.Print("from buflog:", buf.String()) + + // `slog 包提供了 _结构化_ 的日志输出。例如,以 JSON 格式记录日志非常直接。 + jsonHandler := slog.NewJSONHandler(os.Stderr, nil) + myslog := slog.New(jsonHandler) + myslog.Info("hi there") + + // 除了 `msg` 之外,`slog` 输出还可以包含任意数量的键值对。 + myslog.Info("hello again", "key", "val", "age", 25) +} diff --git a/examples/logging/logging.hash b/examples/logging/logging.hash new file mode 100644 index 00000000..4d1c7a70 --- /dev/null +++ b/examples/logging/logging.hash @@ -0,0 +1,2 @@ +38a7ef451859bb4c163df938b3a9d0e5ac293bef +Qd0uCqBlYUn diff --git a/examples/logging/logging.sh b/examples/logging/logging.sh new file mode 100644 index 00000000..a28dd8d9 --- /dev/null +++ b/examples/logging/logging.sh @@ -0,0 +1,17 @@ +# 示例输出; +# 发出的日期和时间将取决于示例运行的时间。 +$ go run logging.go +2023/08/22 10:45:16 standard logger +2023/08/22 10:45:16.904141 with micro +2023/08/22 10:45:16 logging.go:40: with file/line +my:2023/08/22 10:45:16 from mylog +ohmy:2023/08/22 10:45:16 from mylog +from buflog:buf:2023/08/22 10:45:16 hello + +# 这些被换行以便在网站上更清晰地呈现; +# 实际上它们是在单行上发出的。 +{"time":"2023-08-22T10:45:16.904166391-07:00", + "level":"INFO","msg":"hi there"} +{"time":"2023-08-22T10:45:16.904178985-07:00", + "level":"INFO","msg":"hello again", + "key":"val","age":25} diff --git a/examples/xml/xml.go b/examples/xml/xml.go index 8f8085a3..368e81a1 100644 --- a/examples/xml/xml.go +++ b/examples/xml/xml.go @@ -7,11 +7,13 @@ import ( "fmt" ) -// `Plant` 结构将被映射到 `XML` 。 +// `Plant` 结构将被映射到 `XML` 。 +// // 与 `JSON` 示例类似,字段标签包含用于编码器和解码器的指令。 // 这里我们使用了 `XML` 包的一些特性: -// `XMLName` 字段名称规定了该结构的 `XML` 元素名称; -// `id,attrr` 表示 `Id` 字段是一个 `XML` 属性,而不是嵌套元素。 +// +// `XMLName` 字段名称规定了该结构的 `XML` 元素名称; +// `id,attrr` 表示 `Id` 字段是一个 `XML` 属性,而不是嵌套元素。 type Plant struct { XMLName xml.Name `xml:"plant"` Id int `xml:"id,attr"` diff --git a/go.mod b/go.mod index 5b3a4b0c..11c75dc1 100644 --- a/go.mod +++ b/go.mod @@ -8,6 +8,7 @@ require ( ) require ( + github.com/alecthomas/chroma/v2 v2.12.0 // indirect github.com/aws/aws-sdk-go-v2 v1.9.0 // indirect github.com/aws/aws-sdk-go-v2/config v1.7.0 // indirect github.com/aws/aws-sdk-go-v2/credentials v1.4.0 // indirect @@ -20,4 +21,5 @@ require ( github.com/aws/aws-sdk-go-v2/service/sso v1.4.0 // indirect github.com/aws/aws-sdk-go-v2/service/sts v1.7.0 // indirect github.com/aws/smithy-go v1.8.0 // indirect + github.com/dlclark/regexp2 v1.10.0 // indirect ) diff --git a/go.sum b/go.sum index a395d871..a95560ee 100644 --- a/go.sum +++ b/go.sum @@ -2,11 +2,14 @@ github.com/alecthomas/assert v0.0.0-20170929043011-405dbfeb8e38 h1:smF2tmSOzy2Mm github.com/alecthomas/assert v0.0.0-20170929043011-405dbfeb8e38/go.mod h1:r7bzyVFMNntcxPZXK3/+KdruV1H5KSlyVY0gc+NgInI= github.com/alecthomas/chroma v0.8.2 h1:x3zkuE2lUk/RIekyAJ3XRqSCP4zwWDfcw/YJCuCAACg= github.com/alecthomas/chroma v0.8.2/go.mod h1:sko8vR34/90zvl5QdcUdvzL3J8NKjAUx9va9jPuFNoM= +github.com/alecthomas/chroma/v2 v2.12.0 h1:Wh8qLEgMMsN7mgyG8/qIpegky2Hvzr4By6gEF7cmWgw= +github.com/alecthomas/chroma/v2 v2.12.0/go.mod h1:4TQu7gdfuPjSh76j78ietmqh9LiurGF0EpseFXdKMBw= github.com/alecthomas/colour v0.0.0-20160524082231-60882d9e2721 h1:JHZL0hZKJ1VENNfmXvHbgYlbUOvpzYzvy2aZU5gXVeo= github.com/alecthomas/colour v0.0.0-20160524082231-60882d9e2721/go.mod h1:QO9JBoKquHd+jz9nshCh40fOfO+JzsoXy8qTHF68zU0= github.com/alecthomas/kong v0.2.4/go.mod h1:kQOmtJgV+Lb4aj+I2LEn40cbtawdWJ9Y8QLq+lElKxE= github.com/alecthomas/repr v0.0.0-20180818092828-117648cd9897 h1:p9Sln00KOTlrYkxI1zYWl1QLnEqAqEARBEYa8FQnQcY= github.com/alecthomas/repr v0.0.0-20180818092828-117648cd9897/go.mod h1:xTS7Pm1pD1mvyM075QCDSRqH6qRLXylzS24ZTpRiSzQ= +github.com/alecthomas/repr v0.2.0 h1:HAzS41CIzNW5syS8Mf9UwXhNH1J9aix/BvDRf1Ml2Yk= github.com/aws/aws-sdk-go-v2 v1.9.0 h1:+S+dSqQCN3MSU5vJRu1HqHrq00cJn6heIMU7X9hcsoo= github.com/aws/aws-sdk-go-v2 v1.9.0/go.mod h1:cK/D0BBs0b/oWPIcX/Z/obahJK1TT7IPVjy53i/mX/4= github.com/aws/aws-sdk-go-v2/config v1.7.0 h1:J2cZ7qe+3IpqBEXnHUrFrOjoB9BlsXg7j53vxcl5IVg= @@ -37,6 +40,8 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dlclark/regexp2 v1.2.0 h1:8sAhBGEM0dRWogWqWyQeIJnxjWO6oIjl8FKqREDsGfk= github.com/dlclark/regexp2 v1.2.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= +github.com/dlclark/regexp2 v1.10.0 h1:+/GIL799phkJqYW+3YbOd8LCcbHzT0Pbo8zl70MHsq0= +github.com/dlclark/regexp2 v1.10.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= diff --git a/templates/404.tmpl b/templates/404.tmpl new file mode 100644 index 00000000..10aae100 --- /dev/null +++ b/templates/404.tmpl @@ -0,0 +1,15 @@ + + + + + Go by Example: Not Found + + + +
+

Go by Example

+

Sorry, we couldn't find that! Check out the home page?

+{{ template "footer" }} +
+ + diff --git a/templates/example.tmpl b/templates/example.tmpl index 49d2f040..29b185c3 100644 --- a/templates/example.tmpl +++ b/templates/example.tmpl @@ -2,7 +2,7 @@ - Go by Example 中文版: {{.Name}} + Go by Example: {{.Name}} -
-

Go by Example 中文版: {{.Name}}

+

Go by Example: {{.Name}}

{{range .Segs}} {{range .}} @@ -31,7 +30,7 @@ {{.DocsRendered}} @@ -40,7 +39,7 @@ {{end}} {{if .NextExample}}

- 下一个例子: {{.NextExample.Name}} + Next example: {{.NextExample.Name}}.

{{end}} {{ template "footer" }} diff --git a/templates/footer.tmpl b/templates/footer.tmpl index f659096f..916132f5 100644 --- a/templates/footer.tmpl +++ b/templates/footer.tmpl @@ -1,5 +1,5 @@ {{define "footer"}} + by Mark McGranaghan and Eli Bendersky | source | license

{{end}} diff --git a/templates/index.tmpl b/templates/index.tmpl index ba1b5053..520f68bc 100644 --- a/templates/index.tmpl +++ b/templates/index.tmpl @@ -2,18 +2,27 @@ - Go by Example 中文版 + Go by Example
-

Go by Example 中文版

+

Go by Example

- Go 是一门被设计用来构建简单、高效、可信赖软件的开源程序设计语言。 + Go is an + open source programming language designed for + building simple, fast, and reliable software. + Please read the official + documentation + to learn a bit about Go code, tools packages, + and modules.

- Go by Example 是对 Go 基于实践的介绍,包含一系列带有注释说明的示例程序。查看第一个例子或者浏览下面的完整列表吧。 + Go by Example is a hands-on introduction + to Go using annotated example programs. Check out + the first example or + browse the full list below.

- {{if .CodeRun}}{{end}} + {{if .CodeRun}}{{end}} {{.CodeRendered}}