go語言 - 初次見面

語言特性

  • 自動垃圾回收
  • 更豐富的內(nèi)置類型
  • 函數(shù)多返回值
  • 錯誤處理
  • 匿名函數(shù)和閉包
  • 類型和接口
  • 并發(fā)編程
  • 反射
  • 語言交互性

自動垃圾回收

編程中,一個難題就是內(nèi)存管理,如果管理不好對內(nèi)存的使用蔚龙,發(fā)生內(nèi)存泄露可能會引發(fā)嚴重的問題,比如使程序崩潰并炮。C和C++這樣的編程語言补君,提供了指針這樣靈活的類型,但卻必須手動管理內(nèi)存拍霜,增加了編程的復(fù)雜性嘱丢。Java等編程語言本身提供了自動的垃圾回收機制,減少了編程的不少負擔(dān)祠饺。go語言融合了眾多編程語言的優(yōu)秀特點越驻,自然也引入了自動的垃圾回收機制。

所謂垃圾回收道偷,即所有的內(nèi)存分配動作都會被在運行時記錄缀旁,同時任何對該內(nèi)存的使用也都會被記錄,然后垃圾回收器會對所有已經(jīng)分配的內(nèi)存進行跟蹤監(jiān)測勺鸦,一旦發(fā)現(xiàn)有些內(nèi)存已經(jīng)不再被任何人使用并巍,就階段性地回收這些沒人用的內(nèi)存。當(dāng)然换途,因為需要盡量最小化垃圾回收的性能損耗懊渡,以及降低對正常程序執(zhí)行過程的影響,現(xiàn)實中的垃圾回收算法要比這個復(fù)雜得多,比如為對象增加年齡屬性等军拟,但基本原理都是如此剃执。

更豐富的內(nèi)置類型

go語言不僅提供了幾乎所有語言都提供的整形,浮點型等簡單類型吻谋,數(shù)組和字符串等高級類型忠蝗,還提供了字典類型(map),數(shù)組切片(Slice)漓拾。

函數(shù)多返回值

Go語言革命性地在靜態(tài)開發(fā)語言陣營中率先提供了多返回值功能阁最。這個特性讓開發(fā)者可以從原來用各種比較別扭的方式返回多個值的痛苦中解脫出來戒祠,既不用再區(qū)分參數(shù)列表中哪幾個用于輸入,哪幾個用于輸出速种,也不用再只為了返回多個值而專門定義一個數(shù)據(jù)結(jié)構(gòu)姜盈。

go語言函數(shù)返回多個值的簡單示例:

func getName() (firstName, middleName, lastName, nickName string) {
    return "May", "M", "Chen", "Babe"
}

因為返回值都已經(jīng)有名字,因此各個返回值也可以用如下方式來在不同的位置進行賦值配阵,從而提供了極大的靈活性:

func getName() (firstName, middleName, lastName, nickName string) {
    firstName = "May"
    middleName = "M"
    lastName = "Chen"
    nickName = "Babe"
    return
}

并不是每一個返回值都必須賦值馏颂,沒有被明確賦值的返回值將保持默認的空值。
多返回值函數(shù)調(diào)用:

fn, mn, ln, nn := getName()

如果只對該函數(shù)其中的某幾個返回值感興趣的話棋傍,也可以直接用下劃線作為占位符來忽略其他不關(guān)心的返回值:

_, _, lastName, _ := getName()

錯誤處理

Go語言引入了3個關(guān)鍵字用于標準的錯誤處理流程救拉。

  • defer
  • panic
  • recover

與C++和Java等語言中的異常捕獲機制相比, Go語言的錯誤處理機制可以大量減少代碼量瘫拣,讓開發(fā)者也無需僅僅為了程序安全性而添加大量一層套一層的try-catch語句亿絮。
代碼中過多的嵌套,真是讓人抓狂麸拄。

匿名函數(shù)和閉包

在Go語言中派昧,所有的函數(shù)也是值類型,可以作為參數(shù)傳遞拢切。

類型和接口

Go語言不支持繼承和重載蒂萎,而只是支持了最基本的類型組合功能。
Go語言引入了一個無比強大的“非侵入式” 接口的概念淮椰,讓開發(fā)者從以往對C++和Java開發(fā)中的接口管理問題中解脫出來五慈。

go語言簡單的接口使用示例:

type Bird struct {
    ...
}

func (b *Bird) Fly() { //以鳥的方式飛行

}

在實現(xiàn)Bird類型時完全沒有任何IFly的信息。我們可以在另外一個地方定義這個IFly实苞。

type IFly interface { 
    Fly()
}

上面兩個定義看起來絲毫沒有關(guān)系豺撑,現(xiàn)在看看如何使用它們:

func main() {
    var fly IFly = new(Bird) 
    fly.Fly()
}

可以看出,雖然Bird類型實現(xiàn)的時候黔牵,沒有聲明與接口IFly的關(guān)系,但接口和類型可以直接轉(zhuǎn)換爷肝,甚至接口的定義都不用在類型定義之前猾浦,這種比較松散的對應(yīng)關(guān)系可以大幅降低因為接口調(diào)整而導(dǎo)致的大量代碼調(diào)整工作。

并發(fā)編程

Go語言引入了goroutine概念灯抛,它使得并發(fā)編程變得非常簡單金赦。通過使用goroutine而不是裸用操作系統(tǒng)的并發(fā)機制,以及使用消息傳遞而不是共享內(nèi)存來通信对嚼,Go語言讓并發(fā)編程變得更加輕盈和安全夹抗。

通過在函數(shù)調(diào)用前使用關(guān)鍵字go,我們即可讓該函數(shù)以goroutine方式執(zhí)行纵竖。goroutine是一種比線程更加輕盈漠烧、更省資源的協(xié)程杏愤。Go語言通過系統(tǒng)的線程來多路派遣這些函數(shù)的執(zhí)行,使得每個用go關(guān)鍵字執(zhí)行的函數(shù)可以運行成為一個單位協(xié)程已脓。當(dāng)一個協(xié)程阻塞的時候珊楼,調(diào)度器就會自動把其他協(xié)程安排到另外的線程中去執(zhí)行,從而實現(xiàn)了程序無等待并行化運行度液。而且調(diào)度的開銷非常小厕宗,這使得我們能夠創(chuàng)建大量的goroutine,從而可以很輕松地編寫高并發(fā)程序堕担。

Go語言實現(xiàn)了CSP(通信順序進程已慢,Communicating Sequential Process)模型來作為goroutine間的推薦通信方式。在CSP模型中霹购,一個并發(fā)系統(tǒng)由若干并行運行的順序進程組成佑惠,每個進程不能對其他進程的變量賦值。進程之間只能通過一對通信原語實現(xiàn)協(xié)作厕鹃。Go語言用channel(通道) 這個概念來輕巧地實現(xiàn)了CSP模型兢仰。channel的使用方式比較接近Unix系統(tǒng)中的管道(pipe)概念,可以方便地進行跨goroutine的通信剂碴。

另外把将,由于一個進程內(nèi)創(chuàng)建的所有g(shù)oroutine運行在同一個內(nèi)存地址空間中,因此如果不同的goroutine不得不去訪問共享的內(nèi)存變量忆矛,訪問前應(yīng)該先獲取相應(yīng)的讀寫鎖察蹲。Go語言標準庫中的sync包提供了完備的讀寫鎖功能。

反射

Go語言的反射實現(xiàn)了反射的大部分功能催训,但沒有像Java語言那樣內(nèi)置類型工廠洽议,所以無法做到像Java那樣通過類型字符串創(chuàng)建對象實例。

反射最常見的使用場景是做對象的序列化(serialization)漫拭。 例如亚兄,Go語言標準庫的encoding/json、encoding/xml采驻、encoding/gob审胚、encoding/binary等包就大量依賴于反射功能來實現(xiàn)。

go語言發(fā)射的簡單示例:

package main

import (
    "fmt"
    "reflect"
)

type Bird struct {
    Name           string
    LifeExpectance int
}

func (b *Bird) Fly() {
    fmt.Println("I am flying...")
}
func main() {
    sparrow := &Bird{"Sparrow", 3}
    s := reflect.ValueOf(sparrow).Elem()
    typeOfT := s.Type()
    for i := 0; i < s.NumField(); i++ {
        f := s.Field(i)
        fmt.Printf("%d: %s %s = %v\n", i, typeOfT.Field(i).Name, f.Type(),
            f.Interface())
    }
}

輸出結(jié)果:
0: Name string = Sparrow
1: LifeExpectance int = 3

語言交互性

Go語言為了方便的重用現(xiàn)有的C模塊礼旅,提供了Cgo膳叨。
在Go代碼中,可以按Cgo的特定語法混合編寫C語言代碼痘系,然后Cgo工具可以將這些混合的C代碼提取并生成對于C功能的調(diào)用包裝代碼菲嘴。

Go語言使用C模塊的簡單示例:

package main
/*
#include <stdio.h> 
*/
import "C"
import "unsafe"
func main() {
    cstr := C.CString("Hello, world") 
    C.puts(cstr) 
    C.free(unsafe.Pointer(cstr))
}

語言結(jié)構(gòu)

基礎(chǔ)組成

  • 包聲明
  • 引入包
  • 函數(shù)
  • 變量
  • 語句 & 表達式
  • 注釋

簡單示例

學(xué)習(xí)一門語言,從輸出“Hello,world!”開始龄坪。

package main

import "fmt"

func main() {
   fmt.Println("Hello, World!")/* 輸出Hello, World! */
}
  • package main定義了包名昭雌。必須在源文件中非注釋的第一行指明這個文件屬于哪個包。package main表示一個可獨立執(zhí)行的程序悉默,每個 Go 應(yīng)用程序都包含一個名為 main 的包城豁。
  • import "fmt" 告訴 Go 編譯器這個程序需要使用fmt包中的內(nèi)容。
  • func main() 是程序開始執(zhí)行的函數(shù)抄课。main函數(shù)是每一個可執(zhí)行程序所必須包含的唱星。
  • /*...*/ 是多行注釋。你也可以使用單行注釋//
  • fmt.Println("Hello, World!")跟磨,使用fmt包中的輸出函數(shù)Println將“Hello, World!”字符串輸出到控制臺间聊。

執(zhí)行g(shù)o程序

  1. 在你的機器上,安裝go語言開發(fā)環(huán)境抵拘。
  2. 在你設(shè)置的工作目錄下哎榴,新建hello.go文件。
  3. 將上面示例代碼復(fù)制到hello.go文件中僵蛛。
  4. 進入hello.go所在目錄尚蝌,執(zhí)行g(shù)o run hello.go命令行
$ go run hello.go
Hello, World!
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市充尉,隨后出現(xiàn)的幾起案子飘言,更是在濱河造成了極大的恐慌,老刑警劉巖驼侠,帶你破解...
    沈念sama閱讀 212,816評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件姿鸿,死亡現(xiàn)場離奇詭異,居然都是意外死亡倒源,警方通過查閱死者的電腦和手機苛预,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,729評論 3 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來笋熬,“玉大人形庭,你說我怎么就攤上這事勾效”范ǎ” “怎么了睦袖?”我有些...
    開封第一講書人閱讀 158,300評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長旺隙。 經(jīng)常有香客問我,道長骏令,這世上最難降的妖魔是什么蔬捷? 我笑而不...
    開封第一講書人閱讀 56,780評論 1 285
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上周拐,老公的妹妹穿的比我還像新娘铡俐。我一直安慰自己,他們只是感情好妥粟,可當(dāng)我...
    茶點故事閱讀 65,890評論 6 385
  • 文/花漫 我一把揭開白布审丘。 她就那樣靜靜地躺著,像睡著了一般勾给。 火紅的嫁衣襯著肌膚如雪滩报。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 50,084評論 1 291
  • 那天播急,我揣著相機與錄音脓钾,去河邊找鬼。 笑死桩警,一個胖子當(dāng)著我的面吹牛可训,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播捶枢,決...
    沈念sama閱讀 39,151評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼握截,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了烂叔?” 一聲冷哼從身側(cè)響起谨胞,我...
    開封第一講書人閱讀 37,912評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎长已,沒想到半個月后畜眨,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,355評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡术瓮,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,666評論 2 327
  • 正文 我和宋清朗相戀三年康聂,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片胞四。...
    茶點故事閱讀 38,809評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡恬汁,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出辜伟,到底是詐尸還是另有隱情氓侧,我是刑警寧澤,帶...
    沈念sama閱讀 34,504評論 4 334
  • 正文 年R本政府宣布导狡,位于F島的核電站约巷,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏旱捧。R本人自食惡果不足惜独郎,卻給世界環(huán)境...
    茶點故事閱讀 40,150評論 3 317
  • 文/蒙蒙 一踩麦、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧氓癌,春花似錦谓谦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至疲迂,卻和暖如春才顿,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背鬼譬。 一陣腳步聲響...
    開封第一講書人閱讀 32,121評論 1 267
  • 我被黑心中介騙來泰國打工娜膘, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人优质。 一個月前我還...
    沈念sama閱讀 46,628評論 2 362
  • 正文 我出身青樓竣贪,卻偏偏與公主長得像,于是被迫代替她去往敵國和親巩螃。 傳聞我的和親對象是個殘疾皇子演怎,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,724評論 2 351

推薦閱讀更多精彩內(nèi)容