“Go was born out of frustration with existing languages and environments for systems programming.”
Go 是為了作為一個系統語言(systems programming language)而存在的, 它跟天下知名的C語言有同一個父親 - Ken Thompson , 作為一個系統語言, 它並不是直譯式語言, 也非跑在虛擬機(virtual machine)上, 而是貨真價實的像C一樣是先編譯(compile), 而且也是屬於strong and static type的語言, 這表示, 變數型別是預先宣告/決定的, 而且是不能半路變更的, 變數可以像這樣宣告:
var StrVariable string 
var IntVariable int
這邊跟C, Java之類的語言不同的地方是, 型別定義是在後面不是放前面, 剛看到時我以為我會不習慣, 但卻花沒很多時間就適應了, 可能是我在很早以前寫過PASCAL的關係吧, PASCAL也是類似的寫法

但, Go其實還引入了一些dynamic language的特性, 因此在Go內也可以看到未經上面類型的宣告, 就直接指定的敘述, 像是:
strVariable2 := “Hello Go”
這敘述並不代表Go也有dynamic typed的設計, 其實這設計是同時結合了宣告跟指定(assignment), strVariable2並不是沒有型別或動態型別, 因為":=“的關係, 使得strVariable2一開始就被宣告成後面值的型別, 因此上面那行跟下面一樣:
var strVariable2 string
strVariable2 = "Hello Go”
同理, “intVariable2 := 1"這敘述表示intVariable一開始就被宣告成整數(因為1是整數), 所以它還是一個strong typed的設計, 這邊比較要注意到的一個陷阱是”=“和”:=“, 在已宣告過型別的變數, 是用正常的”=“來指定值, 但在未宣告的變數, 必須要用 ”:=“

你不能做的是… "strVariable2 = 1”, 因為strVariable2在前面已經":=“被宣告成字串(string)

在Go, 你一樣可以自定型別, 結構(struct)
type MyString string
type User struct {
    Uid int
    Name string
之後, 你就可以用MyString或是User來宣告變數, 像是
var M1 MyString
var User1 User
User2 := User {1, "julian”}
“type MyString string"有點像是C語言的typedef, 可以讓你以另一個型別(MyString)來替代原本的型別(string), 但它其實還有個妙用, 在後面會再提到

Go是一個functional programming language, 所以它並沒有物件導向觀念

沒有"類別”(class), 沒有物件/實體(object/instance), 但, 它卻有"方法"(method)和"介面"(interface), 聽起來有點四不像, 但其實這部份還蠻有趣的

先說到"方法"(method), 在Go, 你可以為你的型別設計一個"方法", 像是這樣:
func (u *User) Hi() {
    fmt.Printf(“Hi! I’m %s. The %d user.\n”, u.Uid, u.Name)
}
這邊"Hi()“就是屬於"User"的一個方法, 呼叫"User2.Hi()"即可執行它, 方法跟一般的函數一樣, 所不同的是, 前面多了一個”(u *User)“ 以這例子來說, 這邊就是定義了"Hi()"的母體是 *User (*是指標- pointer的意思, 就不在這邊解釋)

這邊有趣的地方是, 你可以為任何自定型別創造"方法”, 包含函數(function), 這在"net/http"內就可以找到類似的應用:



在這例子中, HandlerFunc有一個ServeHTTP的方法, 但HandlerFunc本身其實是一個function

“介面”(interface)也是一個蠻妙的東西, 在Java裡, interface必須要宣告"實作", 亦即"class MyImpl implements MyInterface", 也就是你必須指定某個class實作了某個interface

但在Go, 則是很不一樣, 在Go裡, 你可以宣告一個"介面"(interface) 像是
type MyInterface interface {
    Foo()
}
但你不需要宣告某個型別"實作"了這個interface, 在Go, interface反而比較有"暗示"(imply)的意味, 也就是, 下面的例子, 不用任何宣告, 你可以把MyString自動當成它也可以是一個MyInterface:
func (s MyString) Foo() {}
因為在MyInterface的定義中, 它含有一個"Foo()“, 當你替MyString宣告了一個"Foo()"的方法時, 就自動讓MyString變成了一個實作了MyInterface的型別

下面用一個比較完整的例子來總結:


在這例子中, "CallFoo(MyInterface)"接受一個MyInterface的參數, 並執行它"Foo()"的方法, 由於"Aa”(字串)和"MyHandler"(函數)都是有一個"Foo()“的方法, 所以他們都可以被當做MyInterface作為參數, 同理, 回到前一個HandlerFunc範例, HandlerFunc其實也可以被當做Handler這個interface來使用, 在"net/http"的API中就是用到了這樣一個技巧



via Blogger http://bit.ly/SkFhkC

最近給自己一個作業寫了一個Go版的Facebook API, 本想要實作realtime api時想到, 我需要把這server開放給Facebook server可以存取


看來看去, 好像只有Google自家的GAE有支援Go, 這大概也是因為Go是他們親生子的關係吧, 不過之前一陣子用Heroku用習慣了, 而且, 想說Heroku有支援那麼多的語言平台, 不知道有沒有, 結果翻遍官方的文件, 卻沒發現Go的蹤影

正當要放棄時, 發現, 其實Heroku還蠻威的, 除了支援很多不同的語言平台外, 居然還可以讓你延伸, 而它就是透過開放"Buildpack"這東西:

Heroku Buildpack


而就有一個老兄寫了一個Go用的buildpack (這位老兄在Heroku工作):

Heroku buildpack: Go
Getting start with Go on Heroku

基本上就是建立Procfile和.godir而已, 很簡單, 這樣地鼠同好就有除了GAE以外的選擇囉….

另外就是自己的作業, Facebook API for Go : http://bit.ly/TZ6Zsu
這是一個api實作可以用於server端, realtime API目前還寫的很簡陋, 詳細用法可以看 sample/server.go

這邊一個比較好玩的是, 在Go裡, 你要用這樣的package, 毋須把整個source抓回來build, 而只要使用這樣的方法import:

import facebook “github.com/julianshen/FacebookGoSDK”
這樣是import一個在github上的package, 當你使用"go run"或"go get"之類的來編譯執行程式時, Go自動會上github幫你把這些相關的package取回, 用這個Heroku buildpack做出的環境一樣適用



via Blogger http://bit.ly/TZ6Zsv

明天要在team內開一堂node.js簡介的課, 每次老是用Powerpoint和keynote做投影片, 開始有點乏味了, 所以這次打算嘗試一下

Impress.js

這跟一般投影片製作軟體很不一樣, 正確說來它是一個javascript framework而非一個完整的軟體, 所以也沒啥GUI(似乎也有不少人幫它寫editor), 不過基本說來, 用它來做投影片的方式, 就是拿source codes裡的html檔來改就對了

出來的結果很炫, 但編寫的過程有點小累, 所以後面有點偷懶, 不過也完成了明天要講的投影片:

Introduction to node.js

寫完了之後, 想把它開放出來, 我之前放投影片都依賴了slideshare, 不過slideshare並不能吃這種檔案呀! 所以host又是另一個問題, 所幸, 還有developer的好朋友 - github

github有個好東西叫page, 可以讓你放一些介紹網頁, 也可以有自己的host name像是"julianshen.github.com", 只要照下面這網頁內的說明, 就可以建立屬於自己project的"page":

Creating Project Pages manually



via Blogger http://bit.ly/X0SaGq

今天被問到Go適合用在哪方面, 至今只看了Go兩個晚上的我, 實在很難回答這問題, 先從FAQ找來創立Go的目的說起:

“Go is an attempt to combine the ease of programming of an interpreted, dynamically typed language with the efficiency and safety of a statically typed, compiled language. It also aims to be modern, with support for networked and multicore computing. Finally, it is intended to be fast: it should take at most a few seconds to build a large executable on a single computer. To meet these goals required addressing a number of linguistic issues: an expressive but lightweight type system; concurrency and garbage collection; rigid dependency specification; and so on. These cannot be addressed well by libraries or tools; a new language was called for.”
簡而言之, Go的目標是一個簡單又有效率的語言, 加上一開始設計就考慮網路以及多核, 就姑且說它適合server端的開發吧

事實上, GAE(Google AppEngine)也是有支援Go的 (怎麼說呢, 好歹這也是Google自己親生的呀)

那, 現在開發server端的工具那麼多種, 有什麼樣的理由是選Go優於其他解決方案呢? 以效率來說, 或許比較好吧, 既然它是原生碼, 應該會快一些吧, 但這也沒啥好的benchmark來佐證, 劣勢呢? 以node.js來相比好了(今年看比較多這個, 直覺拿這來做比較), 它不但沒既有的developer做基礎(既有的javascript developer是很大一群的), 也沒有數量很多且快速增長的第三方模組可供利用(雖然, 盲目用npm上的模組, 某種程度上要承擔一定的風險), 最大的問題就是….“文件”

以上前半段是抱怨文, 不過文件不足也沒辦法當啥藉口, 這年頭….“做就對了”…..GAE上關於Go的文件也不是沒有, 跟著做, 就可以做出"Hello World"了, 但剛做完後, 突然楞住想….那…我的html檔案放哪裡? 我總不能每個文件都寫在程式內, 總會有靜態檔案的呀! 有點讓我回到十幾年前寫CGI的感覺

GAE的文件還真找不到, 但在Go的文件http.FileServer的範例可以找到解答, 但要把"FileServer"這個interface跟這件事聯想在一起還真有點不容易, 不過反正就是在程式內要加入下面這行來處理靜態檔案

http.Handle(“/”, http.FileServer(http.Dir(“./static”)))
這範例讓你可以把靜態檔案放在"static"目錄下, 假設你在static目錄下放一個a.html, 那這行的目的就是可以讓你用 http://your_app_host/a.html來存取它

我起始一個範例放在github上, 從這可以看完整的目錄結構, 未來相關範例也會放在這邊

via Blogger http://bit.ly/SixshC

Go沒有exception handling這樣的設計, 所以沒有像java裡的try{} catch{} finally{…}這種東西, 在java裡, 我們會用

try { 
     …..
} finally {  
    in.close();
}
在finally區塊內去做一些善後的工作, 以確保這些善後工作可以在程式執行後不管有沒錯誤發生都可以被執行到, 在Go中, 用的則是defer:


defer後面接的可以是一個closure, 這些closure會在函式執行結束後(return 之後)緊接著被執行, 所以這段程式執行的結果會是這樣:

6
b
e
c
nn
a
——–
1
b
e
a


via Blogger http://bit.ly/RUP5S0