2009年11月17日 星期二

Google Go - C 語言的進化


Go Language 吉祥物 - Gordon 田鼠

自上次更新blog 至今有許多大則的資訊相關新聞
像是 Ubuntu 9.10 與 Android 2.0的發佈
MontaVista 與 3Com 被併購 等等

令個人注目的就是標題上談到的Google所提出的 Go Language
個人認為, 對於喜歡 C 語言的程式設計師而言, Go 會是另一個開發利器

對於Go 的背景資料, 個人就不在此詳加介紹了
在搜尋網站上搜尋就可以輕鬆找到一大堆

Let's Go.

一進入 Go 官方網站, 即說明了Go 語言的特點 - simple, fast, safe, concurrent and fun
的確, 沒有比這更簡潔有力的介紹了

從官網的範例看來, 乍看之下會以為Go又是個了無新意類似 C++/Java 的語言
package main
import "fmt"

func main() {
fmt.Printf("Hello, 世界\n")
}
是吧? 可是官網開頭範例竟然是個天大的陷阱, 從package, import 到 fmt.Printf()
一旦接著好好咀嚼 Tutorial 的話, 會發現 Go 真的蠻奇特的, 甚至與原本所想的相去甚遠

C++/Java 程式設計師第一時間可能是發現到了 - 沒有class, object!
(沒有繼承多型, 我怎麼唬人(誤))
接著會注意不太一樣的variable/function declaration (Goroutine 這是啥!?)
與不太順眼的 if-else, switch, for ...
還有看都沒看過的資料型別 - Slices/Maps/Channels (有 String 囉)
一開始摸不著頭緒的 interface

在語法上 Go 提供了精練且概念呈現較清晰的方式
像是變數宣告:
var Foo [10]int;

且流程控制的語法更為彈性
像是switch:
switch {
case '0' <= c && c <= '9': return c - '0' case 'a' <= c && c <= 'f': return c - 'a' + 10 case 'A' <= c && c <= 'F': return c - 'A' + 10 }
另外像是 function 可以有多個 return values
語法上有諸多新的特性, 就留給大家慢慢發覺

除了語法的改良外

如同 C 語言, Go 依然是以 struct 為主
資料處理的方式, Go 採用了與 C++/Java 物件導向不同的 data - interface
在 OOP 中 data (member) 是依附特定 function (member function)處理
data - interface 中, 並不將資料與介面做緊密的結合, 而僅是有其關係
這樣的方式除了具有彈性外, 資料的操作上也較為直覺, 並且負擔較小
相對地也是達到code reuse 的另一種方式

官網 Tutorial 的 範例 - Sorting:
這是個能夠排序的function (Interface 是 interface 名稱)
func Sort(data Interface) {
for i := 1; i <>
for j := i; j > 0 && data.Less(j, j-1); j-- {
data.Swap(j, j-1);
}
}
}

所制定的 interface

type Interface interface {
Len() int;
Less(i, j int) bool;
Swap(i, j int);
}

如此 Sort 可以套用在任何實作此 Interface 的資料型態
範例中列舉了int array (non-struct)與 day(struct)

type IntArray []int
func (p IntArray) Len() int
{ return len(p); }
func (p IntArray) Less(i, j int) bool
{ return p[i] < p[j]; }
func (p IntArray) Swap(i, j int)
{ p[i], p[j] = p[j], p[i]; }

func ints() {
data := []int{905, 0, 0, 42, 7586, -5467984, 7586};
a := sort.IntArray(data);
sort.Sort(a);
if !sort.IsSorted(a) {
panic()
}
}

type day struct {
num int;
shortName string;
longName string;
}

type dayArray struct {
data []*day;
}

func (p *dayArray) Len() int
{ return len(p.data); }
func (p *dayArray) Less(i, j int) bool
{ return p.data[i].num < p.data[j].num; }
func (p *dayArray) Swap(i, j int)
{ p.data[i], p.data[j] = p.data[j], p.data[i]; }

而其他還有許多值得玩味的部份 - 像是Go 所強調支援的 concurrent 的支援, 與 Memory Model (Go 具有 Garbage Collection)
在此就不詳盡一一介紹了, 官網上的 Tutorial, Package DocumentEffective Go 都是優質的文件資料

如官網 FAQ 所回答的, Go 概念上很多部份源自於 C
然而特性上有混合不少其他類型語言的感覺
相信喜愛 C 的人多半會樂於接受這樣的演進
另外Go 還是發展中的語言, Compiler 還在開發中
目前還缺乏動態連結的能力, 目前僅能編出靜態連結後的執行檔
儘管目前 Go 尚未廣泛地被應用, 然而依然可以從 Go 的設計看出所俱備的潛力

沒有留言:

在 ARM 平台上使用 Function Multi-Versioning (FMV) - 以使用 Android NDK 為例

Function Multi-Versioning (FMV) 過往的 CPU 發展歷程中, x86 平台由於因應各種應用需求的提出, 而陸陸續續加入了不同的指令集, 此外也可能因為針對市場做等級區隔, 支援的數量與種類也不等. 在 Linux 平台上這些 CPU 資訊可以透過...