昨晚清理了自己的pocket,發(fā)現有好多收藏的文章都沒有時間讀,挑了挑,選了golang1.8的release notes和ross cox的新年計劃讀了一下。寫下這篇水文以作記錄。
安裝go1.8
建議使用gvm安裝,可以管理多個版本的golang。
No breaking changes
golang信守承諾,不管你是從1.0開始的老用戶還是1.7開始的新朋友,放心,你們的代碼還能用。(swift程序員哭暈在廁所)
語言層面的修改
作為一門強類型語言中的強類型語言,一個連int和int64都不能隱式類型轉換的語言,golang1.8偷偷做出了一些讓步。golang1.8中,如果兩個結構體的field名稱和類型完全一樣,只是tag不一樣的話,它們之間可以相互convert了。當然,是顯式的。
func example() {
type T1 struct {
X int `json:"foo"`
}
type T2 struct {
X int `json:"bar"`
}
var v1 T1
var v2 T2
v1 = T1(v2) // now legal
}
工具鏈
- 會有一個默認的GOPATH了,默認為$HOME/go
- go get在-insecure這個flag存在時也會走代理了(論走代理的重要性)
- 多了個go bug命令,用于在github上報bug,并自動填好系統信息啥的。
- go doc命令產生的doc會更加有可讀性
- 增加了一個plugin package,不過目前只能用于linux,據說是用于動態(tài)增加插件的,還沒有試用過
運行時與性能
優(yōu)化了gc機制。
優(yōu)化了對并發(fā)時防止多個goroutine同時讀寫一個Map的檢查。
gc pauses明顯縮短,(usually under 100 microseconds and often as low as 10 microseconds. )
編譯速度據說快了20%到30%
標準庫
上面這些release note告訴我們go1.8比1.7好,但是對于寫代碼的我們來說,好像也沒有什么感覺,反倒是標準庫的變化,對我們的影響會比較大。
sort
從前的排序是這么寫的
type People struct {
Name string
Age int
}
type Peoples []People
func (peoples Peoples) Len() int {
return len(peoples)
}
// Swap for sort
func (peoples Peoples) Swap(i,j int){
peoples[i], peoples[j] = peoples[j], peoples[i]
}
// Less for sort
func (peoples Peoples) Less(i,j int) bool{
return peoples[i].Age < peoples[j].Age
}
func main() {
people := Peoples{
{"Gopher", 7},
{"Alice", 55},
{"Vera", 24},
{"Bob", 75},
}
sort.Sort(people)
fmt.Println(people)
}
現在,sort包里面有了一個Slice函數,你以后可以這樣寫了。
// 按名字排序
sort.Slice(people, func(i, j int) bool { return people[i].Name < people[j].Name })
// 按年齡排序
sort.Slice(people, func(i, j int) bool { return people[i].Age < people[j].Age })
HTTP/2 push
不了解push技術的同學可以看看wiki
注意,push技術不是用來從服務端發(fā)送消息通知到前端的(那是websocket干的)。push一般是將原本需要前端發(fā)送一個請求來獲取的資源(腳本,css文件,字體文件,圖片等等)改成由服務端主動發(fā)送。push帶來的好處也很明顯(減少請求,可以指定push順序等等)
下面我們來試用一下go1.8里面的push。
創(chuàng)建項目http2push,并創(chuàng)建文件main.go
package main
import (
"fmt"
"log"
"net/http"
)
const mainJS = `console.log("hello world");`
const indexHTML = `<html>
<head>
<title>Hello</title>
<script src="/main.js"></script>
</head>
<body>
</body>
</html>
`
func main() {
http.HandleFunc("/main.js", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, mainJS)
})
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/" {
http.NotFound(w, r)
return
}
pusher, ok := w.(http.Pusher)
if ok { // Push is supported. Try pushing rather than waiting for the browser.
if err := pusher.Push("/main.js", nil); err != nil {
log.Printf("Failed to push: %v", err)
}
}
fmt.Fprintf(w, indexHTML)
})
log.Fatal(http.ListenAndServeTLS(":8080", "cert.pem", "key.pem", nil))
}
打開命令行,進入項目目錄,首先運行
go run $GOROOT/src/crypto/tls/generate_cert.go --host 127.0.0.1
運行結果生成cert.pem和key.pem,然后運行
go run main.go
打開chrome,輸入
https://localhost:8080/
打開開發(fā)者工具,可以看到main.js是被服務端主動push過來的,而不是瀏覽器主動發(fā)送的get請求。
支持http server graceful shutdown
調用server.Close()的話服務器會直接關閉,而調用server.Shutdown()的話服務器會處理完畢所有已有的連接然后再關閉。
期待
ross cox的目標
Russ Cox說2017年要搞golang的包管理,
"In particular, other language ecosystems have really raised the bar for what people expect from package management, and the open source world has mostly agreed on semantic versioning, which provides a useful base for inferring version compatibility. "
不禁眼眶一濕。
比期待更期待
泛型泛型泛型。。。泛型有了,map,reduce啥的還會遠嗎。ross大神說:
"Nothing sparks more heated arguments among Go and non-Go developers than the question of whether Go should have support for generics (or how many years ago that should have happened). I don’t believe the Go team has ever said “Go does not need generics.” What we have said is that there are higher-priority issues facing Go. For example, I believe that better support for package management would have a much larger immediate positive impact on most Go developers than adding generics. But we do certainly understand that for a certain subset of Go use cases, the lack of parametric polymorphism is a significant hindrance."
大神最后給我們灌了一大碗雞湯,并表示,他覺得雖然golang的泛型在2017年不會發(fā)生,但是他不會停止探索在golang上設計泛型。
"When I first started thinking about generics for Go in 2008, the main examples to learn from were C#, Java, Haskell, and ML. None of the approaches in those languages seemed like a perfect fit for Go. Today, there are newer attempts to learn from as well, including Dart, Midori, Rust, and Swift.
It’s been a few years since we ventured out and explored the design space. It is probably time to look around again, especially in light of the insight about mutability and the additional examples set by newer languages. I don’t think generics will happen this year, but I’d like to be able to say I understand the solution space better."