探索Google Go語(yǔ)言(一)
看到網(wǎng)上有些人說(shuō)Go是python 4.0,對(duì)此看法,我不敢茍同。從本質(zhì)上講,這兩個(gè)是完全不同的語(yǔ)言。go是靜態(tài)型編譯語(yǔ)言,python是動(dòng)態(tài)型解釋語(yǔ)言(腳本語(yǔ)言);go的執(zhí)行速度屬于微秒級(jí),可精確到納秒,而python屬于毫秒級(jí),根本無(wú)法比;go完全支持指針,python不支持,只有引用。閑話不多說(shuō),下面就來(lái)看看go長(zhǎng)得啥樣子。如果你有C/C++,JAVA,C#,python等語(yǔ)言基礎(chǔ),對(duì)linux有些了解,我相信你一定會(huì)很快會(huì)對(duì)go有初步了解。
老規(guī)矩,先來(lái)個(gè)hello world。
hello.go
- package main //聲明本文件的package名
- import "fmt" //import語(yǔ)言的fmt庫(kù)——用于輸出
- func main() {
- var str string = "hello world"
- //str := "hello world"
- //var str = "hello word"
- fmt.Println(str)
- }
有兩種方式可以解釋運(yùn)行
1、先編譯:go build hello.go
再運(yùn)行:./hello
2、也可以直接進(jìn)行編譯運(yùn)行(其實(shí)下面這個(gè)命令實(shí)際是編譯成hello.out再執(zhí)行):go run hello.go
對(duì)于習(xí)慣了C系列語(yǔ)言的同學(xué)來(lái)說(shuō),會(huì)對(duì)go的語(yǔ)法很不習(xí)慣。***,go沒(méi)有使用“;”作為語(yǔ)句結(jié)束標(biāo)志;第二,go是變量在類型前面,變量初始化還可以如注釋的那兩行語(yǔ)句,不用指定類型,go編譯器可以從初始化表達(dá)式的右值導(dǎo)出該變量應(yīng)該聲明為哪種類型,這讓go看起來(lái)有點(diǎn)像動(dòng)態(tài)語(yǔ)言,這也可能為什么有人說(shuō)它是python 4.0的原因吧。
go很可能是***個(gè)將代碼風(fēng)格進(jìn)行強(qiáng)制統(tǒng)一的語(yǔ)言,例如go語(yǔ)言要求public的變量名必須以大寫(xiě)字母開(kāi)頭,private變量則以小寫(xiě)字母開(kāi)關(guān),這種做法不僅免除了public,private關(guān)鍵字,更重要的是統(tǒng)一了風(fēng)格。還有,對(duì)于判斷語(yǔ)句,如果你寫(xiě)成這樣:
- if str == "descur"{
- ....
- }
- else{
- ....
- }
是不能編譯通過(guò)的,一定要寫(xiě)成這樣:
- if str == "descusr"{
- ...
- }else{
- ...
- }
這可能對(duì)那些在微軟懷抱中長(zhǎng)大的孩子來(lái)會(huì)很痛苦,但對(duì)像我這些有代碼潔癖的人來(lái)說(shuō)未嘗不是好事。其實(shí)統(tǒng)一了代碼風(fēng)格,進(jìn)行團(tuán)隊(duì)合作時(shí)是很有益的。
編程哲學(xué)
C語(yǔ)言是純過(guò)程式的,這和它產(chǎn)生的歷史背景有關(guān)。C#/JAVA語(yǔ)言則是高度的面向?qū)ο笳Z(yǔ)言,典型表現(xiàn)是它們的體系里不存在孤立的方法,這些方法必須是屬于某個(gè)類。而go沒(méi)有去否認(rèn)任何一方,而是用批判吸收的眼光,綜合了各種編程思想,融合眾家之長(zhǎng),極力維持語(yǔ)言特性的簡(jiǎn)潔,力求小而精,越深入go,你就會(huì)發(fā)現(xiàn)go真的是太簡(jiǎn)潔了。
從編程范式的角度看,go是變革派,不是改良派。
雖然go屬于面向?qū)ο笳Z(yǔ)言,但在go的概念里沒(méi)有面向?qū)ο筮@個(gè)概念,只有結(jié)構(gòu)體。go的類具有高度的粒子性,如下面的代碼:
- type rect struct {
- width, height int
- }
- func (r *rect) area() int { //求面積
- return r.width * r.height
- }
- func (r *rect) perimeter() int{ //求周長(zhǎng)
- return 2*(r.width + r.height)
- }
- func main() {
- r := rect{width: 10, height: 15}
- fmt.Println("面積: ", r.area())
- fmt.Println("周長(zhǎng): ", r.perimeter())
- rp := &r
- fmt.Println("面積: ", rp.area())
- fmt.Println("周長(zhǎng): ", rp.perimeter())
- }
類和類方法完全分開(kāi),只有在初始化對(duì)象后才進(jìn)行調(diào)用,減少了耦合度。go沒(méi)有構(gòu)造函數(shù)和析構(gòu)函數(shù)。由于go語(yǔ)言中沒(méi)有虛函數(shù),也就沒(méi)有vptr,支持構(gòu)造函數(shù)和析構(gòu)函數(shù)就沒(méi)有太大價(jià)值。
其次,go語(yǔ)言反對(duì)函數(shù)和操作符重載,而C#,C++,和JAVA允許同名函數(shù)或者操作符,只要它們的參數(shù)列表不同。雖然重載解決了一小部分OOP問(wèn)題,但卻給這些語(yǔ)言帶來(lái)了極大的負(fù)擔(dān),并且這種方法對(duì)解決問(wèn)題問(wèn)題并沒(méi)有帶來(lái)多大價(jià)值,所以go就不提供重載。
再次,go反對(duì)繼承,反對(duì)虛函數(shù)和虛函數(shù)重載。其實(shí),go也提供了繼承,只不過(guò)采用了組合的方法來(lái)提供:
- type Car struct{
- Base
- ...
- }
- func (color *Car) Drive(){
- ...
- }
go語(yǔ)言中的接口與其他語(yǔ)言***的一點(diǎn)區(qū)別是它的非侵入性。在C#等面向?qū)ο笳Z(yǔ)言中,為了實(shí)現(xiàn)接口,你需要從接口繼承,如:
- public interface IBankAccount
- {
- void PayIn(decimal amount);
- }
- class SaverAccount : IBankAccount
- {
- public void PayIn(decimal amount)
- {
- Console.WriteLine("This is PayIn");
- }
- }
在go語(yǔ)言中,實(shí)現(xiàn)類的時(shí)候無(wú)需從接口派生,如:
- type SaverAccount struct{ //go
- ...
- }
- var saveAccount IBankAccount = new(SaveAccount)
只要實(shí)現(xiàn)了IBankAccount要求的所有方法,就實(shí)現(xiàn)了該接口,可以進(jìn)行賦值,相當(dāng)原子性。
原文鏈接:http://www.cnblogs.com/descusr/archive/2012/11/07/2759575.html
【編輯推薦】
























