Go 2 中你最期待什么功能?
Posted Go语言中文网
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Go 2 中你最期待什么功能?相关的知识,希望对你有一定的参考价值。
正如许多人所指出的那样,这个特性将出现在开发人员已经很多年了,我真的很喜欢建立漂亮的网络应用程序是如此简单。使用Go的模板语言,即使是最简单的任务 - 例如将一个项目列表打印成一个句子 - 对于初学者来说也是难以企及的,特别是与Rails的Enumerable#to_sentence
的相比。
log.StructuredLogger
,实现者可以做出自己的选择:func WithLogger(l log.StructuredLogger) Option
return func(f *Foo) *Foo
f.logger = l
return f
我把这样一个接口的草图快速勾勒了出来。
// StructuredLogger is an interface for structured logging.
type StructuredLogger interface
// Log logs a message.
Log(message string, fields ...LogField)
// LogAt logs a message at the provided level. Perhaps we could also have
// Debugf, Infof, etc, but I think that might be too limiting for the standard
// library.
LogAt(level LogLevel, message string, fields ...LogField)
// LogEntry logs a complete log entry. See LogEntry for the default values if
// any fields are missing.
LogEntry(entry *LogEntry)
// LogLevel is the underlying log level.
type LogLevel uint8
// LogEntry represents a single log entry.
type LogEntry struct
// Level is the log level. If no level is provided, the default level of
// LevelError is used.
Level LogLevel
// Message is the actual log message.
Message string
// Fields is the list of structured logging fields. If two fields have the same
// Name, the later one takes precedence.
Fields []*LogField
// LogField is a tuple of the named field (a string) and its underlying value.
type LogField struct
Name string
Value interface
围绕着实际的接口会是什么样子,如何最小化分配,以及如何最大化兼容性,有很多讨论,但目标是定义一个其他日志库可以轻松实现的接口。
在我的Ruby时代,有大量的Ruby版本管理器,每个都有自己的dotfile名称和语法。Fletcher Nichol设法说服了这些Ruby版本管理器的所有维护者,使其标准化为.ruby-version,只需写一个gist[27]。我希望我们能在Go 社区中使用结构化日志记录做类似的事情。
多错误处理有很多情况,特别是对于后台工作或周期性任务,系统可能会并行处理一些事情或在出现错误时继续处理。在这些情况下,返回一个多重错误是有帮助的。在标准库中没有对处理错误集合的内置支持。
围绕多错误处理有清晰简洁的标准库定义,可以统一社区,减少错误处理不当的风险,正如我们看到的错误包装(wrap)和解包(unwrap)。
针对 JSON Marshal的error说到error,你知道吗,将error类型嵌入到一个结构字段中,然后将该结构作为JSON进行marshal
,将 "error"字段marshal
为?
// https://play.golang.org/p/gl7BPJOgmjr
package main
import (
"encoding/json"
"fmt"
)
type Response1 struct
Err error `json:"error"`
func main()
v1 := &Response1Err: fmt.Errorf("oops")
b1, err := json.Marshal(v1)
if err != nil
panic(err)
// got: "error":
// want: "error": "oops"
fmt.Println(string(b1))
至少对于内置的errorString
类型,Go应该为.Error()的结果进行marshal
。另外,对于Go 2.0来说,当试图marshal
一个没有实现自定义marshal
逻辑的error类型时,JSON marshal
会返回一个错误。
仅举一个例子,http.DefaultClient
和http.DefaultTransport
都是具有共享状态的全局变量。http.DefaultClient
没有配置超时,这使得DOS你自己的服务和创造瓶颈变得很容易。许多软件包都会突变,http.DefaultClient
和http.DefaultTransport
,这可能会浪费开发者数天的资源来追踪错误。
Go 2.0应该把这些东西变成私有的,并通过一个函数调用来公开它们,返回有关变量的唯一分配。另外,Go 2.0还可以实现 "冻结 "的全局变量,这样它们就不能被其他包所改变。
从软件供应链的角度来看,我也担心这类问题。如果我可以开发一个有用的包,秘密地修改http.DefaultTransport
,使用一个自定义的RoundTripper
,将你的所有流量通过我的服务器输送出去,那将是一个非常糟糕的瞬间。
这更像是一个"不为人所知或有据可查的事情"。大多数示例(包括 Go 文档中的示例)都鼓励执行以下操作,以便通过 Web 请求对 JSON 进行marshal或渲染 html:
func toJSON(w http.ResponseWriter, i interface)
if err := json.NewEncoder(w).Encode(i); err != nil
http.Error(w, "oops", http.StatusInternalServerError)
func toHTML(w http.ResponseWriter, tmpl string, i interface)
if err := templates.ExecuteTemplate(w, tmpl, i); err != nil
http.Error(w, "oops", http.StatusInternalServerError)
然而,对于这两种情况,如果i
足够大,有可能在发送第一个字节(和200状态码)后,编码/执行失败。在这一点上,请求是无法恢复的,因为你无法改变响应代码。
大体上被接受的缓解方案是先渲染,然后复制到w。这仍然会有很小的出错空间(由于连接问题导致向w写入失败),但它确保在发送第一个字节之前,编码/执行是成功的。然而,在每个请求中分配一个字节片是很昂贵的,所以你通常会使用缓冲池[28]。
这种方法非常冗长,并将许多不必要的复杂性推给实现者。相反,如果 Go能自动处理此缓冲池管理,可能会使用EncodePooled
等函数,那就更好了。
Go仍然是我最喜欢的编程语言之一,这就是为什么我觉得可以强调这些批评的原因。与任何编程语言一样,Go也在不断发展。你认为这些是好主意吗?还是说它们是糟糕的建议?请在Twitter[29]上告诉我。
参考资料What I\'d like to see in Go 2.0: https://www.sethvargo.com/what-id-like-to-see-in-go-2
[2]Learning Chef: https://www.amazon.com/Learning-Chef-Configuration-Management-Automation/dp/1491944935
[3]text/template
: https://pkg.go.dev/text/template
html/template
: https://pkg.go.dev/html/template
Consul Template: https://github.com/hashicorp/consul-template
[6]Hugo: https://gohugo.io/
[7]相当广泛的辅助函数列表: https://gohugo.io/functions/
[8]Exposure Notification: https://g.co/ens
[9]无法逃脱反射: https://github.com/google/exposure-notifications-verification-server/blob/0ec489ba95137d5be10e1617d1dcdc2d1ee6e5e9/pkg/render/renderer.go#L232-L280
[10]Go 1.18: https://tip.golang.org/doc/go1.18#text/template
[11]改善 for-loop 人体工程学设计: https://github.com/golang/go/issues/24282
[12]在每次迭代中重新定义范围循环变量: https://github.com/golang/go/issues/20733
[13]会通过统一的伪随机来选择case的: https://golang.org/ref/spec#Select_statements
[14]log
: https://pkg.go.dev/log
Go 中不乏结构化日志库: https://www.client9.com/logging-packages-in-golang/
[16]apex/log: https://github.com/apex/log
[17]go-kit/log: https://github.com/go-kit/kit/tree/master/log
[18]golang/glog: https://github.com/golang/glog
[19]hashicorp/go-hclog: https://github.com/hashicorp/go-hclog
[20]inconshreveable/log15: https://github.com/inconshreveable/log15
[21]rs/zerolog: https://github.com/rs/zerolog
[22]sirupsen/logrus: https://github.com/sirupsen/logrus
[23]uber/zap: https://github.com/uber-go/zap
[24]go-retry: https://github.com/sethvargo/go-retry
[25]go-envconfig: https://github.com/sethvargo/go-envconfig
[26]go-githubactions: https://github.com/sethvargo/go-githubactions
[27]gist: https://gist.github.com/fnichol/1912050
[28]使用缓冲池: https://github.com/google/exposure-notifications-verification-server/blob/08797939a56463fe85f0d1b7325374821ee31448/pkg/render/html.go#L65-L91
[29]Twitter: https://twitter.com/sethvargo
推荐阅读
Go 原生并发原语和最佳实践
iOS 14四大新功能:哪个是你最期待的?
iOS 14 可能不是我们所见过的最大的 iOS 更新,但是它的确提供了粉丝多年来一直想要的某些功能。接下来我们就来看看在 iOS 14 中,用户期待多年的四大功能。
—— 推荐阅读 ——
你有「在看」吗 ?
以上是关于Go 2 中你最期待什么功能?的主要内容,如果未能解决你的问题,请参考以下文章
八一建军节阅兵,你最期待哪款战机梯队飞跃天安门,歼-20隐身战斗机如何