因此,过去几天的热门话题是来自Google的新语言Go.假设你是所有迷恋程序设计语言的极客,就像我一样,你已经全部下载,构建它,并运行你的"Hello,世界"程序(使用UTF-8发明者编写的语言不是很好吗?) .您已经阅读了教程,Effective Go和其他一些文档.
现在,你打算用它做什么?
我想看一些炫耀Go的力量的演示.你能在简短的节目中做些什么?展示你最好的示例代码.虽然在你需要不断变化的项目过程中与许多程序员组成的团队编写并维护一个大型代码库之后,才能真正衡量一种语言的真正衡量标准,看看你能在有限数量的情况下做多少工作.代码确实有助于展示语言的表达能力.我希望看到简短,完整的程序,真正体现Go的独特新功能; 不只是片段或"你好,世界".
所以,发布一些你用Go编写的很酷的代码.利用其独特的功能,如goroutines和并发通道,或基于接口的类型系统.你能写一个原始的聊天服务器,还是很酷的IRC机器人?实现可扩展到多个核心的并行Mandelbrot集?为一些小语言写一个翻译?你能用30行做到这一切吗?
我任意选择30,就像你可以装入Stack Overflow代码块一样,没有它溢出并得到一个滚动条; 它应该足够做一些有趣的事情,不要打太多高尔夫球,但要足够短,以便让每个人都注意快速演示.例如,只需稍微重新格式化,示例Web服务器就应该能够适应(不计算数据).
告诉我们您的Go代码!
这是我编写的Web代理,用于提供对需要HTTP基本身份验证的Web服务的未经身份验证的访问.我需要它用于内部的东西(并且仍然使用它):
package main import ( "flag" "log" "net/http" "net/url" ) var target = flag.String("target", "http://www.google.com/", "Where to go.") var addr = flag.String("listen", ":12345", "Address/port on which to listen.") var auth = flag.String("auth", "", "Authorization header to add (optional).") func main() { flag.Parse() targetUrl, uerr := url.Parse(*target) if uerr != nil { log.Fatalf("Error parsing target ``%s'': ", target, uerr.String()) } proxy := http.ReverseProxy{Director: func(req *http.Request) { req.URL.Scheme = targetUrl.Scheme req.URL.Host = targetUrl.Host req.Host = targetUrl.Host if *auth != "" { req.Header.Set("Authorization", *auth) } }} log.Fatal(http.ListenAndServe(*addr, &proxy)) }
这使得钟面的PNG(在stdout上)显示当前时间.它几乎没有高尔夫球,适合三十行,所以代码不是那么干净.
package main import ("image"; "image/png"; "math"; "bufio"; "os"; "time") const clock_size = 200; const radius = clock_size / 3; var colour image.RGBAColor; func circle (clock *image.RGBA) { for angle := float64(0); angle < 360; angle++ { radian_angle := math.Pi * 2 * angle / 360; x := radius * math.Sin (radian_angle) + clock_size/2; y := radius * math.Cos (radian_angle) + clock_size/2; clock.Set (int (x), int (y), colour);}} func hand (clock *image.RGBA, angle float64, length float64) { radian_angle := math.Pi * 2 * angle; x_inc := math.Sin (radian_angle); y_inc := -math.Cos (radian_angle); for i := float64(0); i < length; i++ { x := i * x_inc + clock_size/2; y := i * y_inc + clock_size/2; clock.Set (int (x), int (y), colour);}} func main () { clock := image.NewRGBA (clock_size, clock_size); colour.A = 255; circle (clock); time := time.LocalTime (); hand (clock, (float64(time.Hour) + float64(time.Minute)/60)/12, radius*0.6); // hour hand hand (clock, (float64(time.Minute) + float64(time.Second)/60)/60, radius*0.8); // minute hand out := bufio.NewWriter(os.Stdout); defer out.Flush(); png.Encode(out, clock); }
像那样运行它
8.out > clock.png
注意所有那些float64演员?我从未见过像Go这样严格的语言.
这是修复的相同代码go fix
(和一些手动调整),然后使用自动格式化go fmt
.手动插入的一些换行符.
package main import ( "bufio" "image" "image/color" "image/png" "math" "os" "time" ) const clock_size = 200 const radius = clock_size / 3 var colour color.RGBA func circle(clock *image.RGBA) { for angle := float64(0); angle < 360; angle++ { radian_angle := math.Pi * 2 * angle / 360 x := radius*math.Sin(radian_angle) + clock_size/2 y := radius*math.Cos(radian_angle) + clock_size/2 clock.Set(int(x), int(y), colour) } } func hand(clock *image.RGBA, angle float64, length float64) { radian_angle := math.Pi * 2 * angle x_inc := math.Sin(radian_angle) y_inc := -math.Cos(radian_angle) for i := float64(0); i < length; i++ { x := i*x_inc + clock_size/2 y := i*y_inc + clock_size/2 clock.Set(int(x), int(y), colour) } } func main() { clock := image.NewRGBA(image.Rect(0, 0, clock_size, clock_size)) colour.A = 255 circle(clock) time := time.Now() hand(clock, (float64(time.Hour())+float64(time.Minute())/60)/12, radius*0.6) // hour hand hand(clock, (float64(time.Minute())+float64(time.Second())/60)/60, radius*0.8) // minute hand out := bufio.NewWriter(os.Stdout) defer out.Flush() png.Encode(out, clock) }
我真的很喜欢go的渠道和select
声明,因此,这件事显示了表达“去并在一定时间内获得尽可能多的东西”的概念是多么容易。
这会在300毫秒内生成尽可能多的随机数,并返回当时最大的随机数。
package main import ( "fmt" "math/rand" "time" ) func main() { timeout := time.After(300 * time.Millisecond) numbers := make(chan int) // This channel will be used var numberCount int = 0 var maxNumber int = 0 // Start putting random numbers on the numbers channel go func() { for { numbers <- rand.Int() } }() for { select { case <- timeout: fmt.Printf("%v numbers generated. Max number found: %v.\n", numberCount, maxNumber) return case number := <- numbers: numberCount++ if number > maxNumber { maxNumber = number } } } }