来自Negroni库的交互式代码片段,它是地道的Go的例子
其他语言在提供一些核心功能,比如HTTP处理的时候,往往需要依赖第三方库。但是Go语言在这一点上很不同,它的标准库非常强大。如果你认为Go标准库没有强大到可以做你想做的事情,那么我说你错了。Go语言标准库难以置信的强大,值得你花时间阅读它的代码,学习它实现的模式。
func (srv *Server) ListenAndServe() error {
addr := srv.Addr
if addr == "" {
addr = ":http"
}
ln, err := net.Listen("tcp", addr)
if err != nil {
return err
}
return srv.Serve(tcpKeepAliveListener{ln.(*net.TCPListener)})}
Go标准库中的ListenAndServe函数片段。如果你写过Go程序,你可能已经调用过这个函数很多次了,但是你曾经花时间看过它的实现么?去点击上面的代码片段吧。
幻灭的低谷中的幻灭感来自于这样的事实:你还在用其他语言的模式来想问题,而且你还没有完全探索过Go能提供给你什么。下面是一些好玩的事情,你可以做一下来打破困境,进一步探索这门语言中好玩的事。
go generate
现在来看看go generate。go generate是一个你可以用来自动自成Go代码的命令。你可以结合例如jsonenums(一个用于为枚举类型自动生成JSON编组样板代码的类库)这样的元编程来使用go generate快速自动实现重复乏味代码的编写。在Go标准类库里面已经有大量可以用于解析AST的接口,而AST使得编写元编程工具更简单,更容易。在会议上,有另外两次讨论(Go语言中的元编程实践和拥抱标准类库)谈及到了这一点。
func main() {
flag.Parse()
if len(*typeNames) == 0 {
log.Fatalf("the flag -type must be set")
}
types := strings.Split(*typeNames, ",")
// Only one directory at a time can be processed, and the default is ".".
dir := "."
if args := flag.Args(); len(args) == 1 {
dir = args[0]
} else if len(args) > 1 {
log.Fatalf("only one directory at a time")
}
pkg, err := parser.ParsePackage(dir, *outputSuffix+".go")
if err != nil {
log.Fatalf("parsing package: %v", err)
}
var ysis = struct {
Command string
PackageName string
TypesAndValues map[string][]string
}{
Command: strings.Join(os.Args[1:], " "),
PackageName: pkg.Name,
TypesAndValues: make(map[string][]string),
}
// Run generate for each type.
for _, typeName := range types {
values, err := pkg.ValuesOfType(typeName)
if err != nil {
log.Fatalf("finding values for type %v: %v", typeName, err)
}
ysis.TypesAndValues[typeName] = values
var buf bytes.Buffer
if err := generatedTmpl.Execute(&buf, ysis); err != nil {
log.Fatalf("generating code: %v", err)
}
src, err := format.Source(buf.Bytes())
if err != nil {
// Should never happen, but can arise when developing this code.
// The user can compile the output to see the error.
log.Printf("warning: internal error: invalid Go generated: %s", err)
log.Printf("warning: compile the package to yze the error")
src = buf.Bytes()
}
output := strings.ToLower(typeName + *outputSuffix + ".go")
outputPath := filepath.Join(dir, output)
if err := ioutil.WriteFile(outputPath, src, 0644); err != nil {
log.Fatalf("writing output: %s", err)
}
}}
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-28542-3.html
真的不太喜欢这次的冷色调
收二手家电者的广告词
好好笑