探索Go語言(一)


  看到網上有些人說Go是python 4.0,對此看法,我不敢苟同。從本質上講,這兩個是完全不同的語言。go是靜態型編譯語言,python是動態型解釋語言(腳本語言);go的執行速度屬於微秒級,可精確到納秒,而python屬於毫秒級,根本無法比;go完全支持指針,python不支持,只有引用。閑話不多說,下面就來看看go長得啥樣子。如果你有C/C++,JAVA,C#,python等語言基礎,對linux有些了解,我相信你一定會很快會對go有初步了解。

  (本文不是教程,如果想學具體的go語言,請穩步至:[摘]Go 語言簡介(上)— 語法 和[摘]Go 語言簡介(下)— 特性

  老規矩,先來個hello world。

  

hello.go

  

package main //聲明本文件的package名   
import "fmt" //import語言的fmt庫——用於輸出   
func main() {
  var str string = "hello world"
  //str := "hello world"
  //var str = "hello word"
fmt.Println(str
) }

  

運行

  有兩種方式可以解釋運行

  1、先編譯:go build hello.go

    再運行:./hello

  2、也可以直接進行編譯運行(其實下面這個命令實際是編譯成hello.out再執行):go run hello.go

  對於習慣了C系列語言的同學來說,會對go的語法很不習慣。第一,go沒有使用“;”作為語句結束標志;第二,go是變量在類型前面,變量初始化還可以如注釋的那兩行語句,不用指定類型,go編譯器可以從初始化表達式的右值導出該變量應該聲明為哪種類型,這讓go看起來有點像動態語言,這也可能為什么有人說它是python 4.0的原因吧。

  go很可能是第一個將代碼風格進行強制統一的語言,例如go語言要求public的變量名必須以大寫字母開頭,private變量則以小寫字母開關,這種做法不僅免除了public,private關鍵字,更重要的是統一了風格。還有,對於判斷語句,如果你寫成這樣:

if str == "descur"{
    ....
}
else{
    ....
}

是不能編譯通過的,一定要寫成這樣:

if str == "descusr"{
    ...
}else{
    ...
}

這可能對那些在微軟懷抱中長大的孩子來會很痛苦,但對像我這些有代碼潔癖的人來說未嘗不是好事。其實統一了代碼風格,進行團隊合作時是很有益的。

編程哲學

  C語言是純過程式的,這和它產生的歷史背景有關。C#/JAVA語言則是高度的面向對象語言,典型表現是它們的體系里不存在孤立的方法,這些方法必須是屬於某個類。而go沒有去否認任何一方,而是用批判吸收的眼光,綜合了各種編程思想,融合眾家之長,極力維持語言特性的簡潔,力求小而精,越深入go,你就會發現go真的是太簡潔了。

  從編程范式的角度看,go是變革派,不是改良派。

  雖然go屬於面向對象語言,但在go的概念里沒有面向對象這個概念,只有結構體。go的類具有高度的粒子性,如下面的代碼:

 1 type rect struct {
 2      width, height int
 3 }
 4 
 5 func (r *rect) area() int { //求面積
 6      return r.width * r.height 
 7 }   
 8 
 9 func (r *rect) perimeter() int{ //求周長
10      return 2*(r.width + r.height) 
11 }   
12 
13 func main() {
14      r := rect{width: 10, height: 15}
15      fmt.Println("面積: ", r.area())
16      fmt.Println("周長: ", r.perimeter()) 
17      rp := &r
18      fmt.Println("面積: ", rp.area())
19      fmt.Println("周長: ", rp.perimeter()) 
20 }

類和類方法完全分開,只有在初始化對象后才進行調用,減少了耦合度。go沒有構造函數和析構函數。由於go語言中沒有虛函數,也就沒有vptr,支持構造函數和析構函數就沒有太大價值。

  其次,go語言反對函數和操作符重載,而C#,C++,和JAVA允許同名函數或者操作符,只要它們的參數列表不同。雖然重載解決了一小部分OOP問題,但卻給這些語言帶來了極大的負擔,並且這種方法對解決問題問題並沒有帶來多大價值,所以go就不提供重載。

  再次,go反對繼承,反對虛函數和虛函數重載。其實,go也提供了繼承,只不過采用了組合的方法來提供:

1 type Car struct{
2     Base
3     ...
4 }
5 
6 func (color *Car) Drive(){
7     ...
8 }

  放棄了大量的OOP特性后,go提供了一份相當棒的功能:接口。你可能會有疑問,所有面向對象語言也有接口啊?但那些面向對象語言的接口都基本上一樣,而go的卻跟它們不一樣。

  go語言中的接口與其他語言最大的一點區別是它的非侵入性。在C#等面向對象語言中,為了實現接口,你需要從接口繼承,如:

public interface IBankAccount
{
    void PayIn(decimal amount);
}
class SaverAccount : IBankAccount
{

    public void PayIn(decimal amount)
    {
        Console.WriteLine("This is PayIn");
    }

}

在go語言中,實現類的時候無需從接口派生,如:

type SaverAccount  struct{   //go
    ...
}

var saveAccount IBankAccount = new(SaveAccount)

只要實現了IBankAccount要求的所有方法,就實現了該接口,可以進行賦值,相當原子性。
(未完待續...困了)

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM