Go語言于2009年11月正式宣布推出,成為開放源代碼項(xiàng)目,并在Linux及Mac OS X平臺上進(jìn)行了實(shí)現(xiàn),后追加Windows系統(tǒng)下的實(shí)現(xiàn)。

創(chuàng)新互聯(lián)專注于企業(yè)成都全網(wǎng)營銷、網(wǎng)站重做改版、元寶網(wǎng)站定制設(shè)計(jì)、自適應(yīng)品牌網(wǎng)站建設(shè)、HTML5建站、商城網(wǎng)站定制開發(fā)、集團(tuán)公司官網(wǎng)建設(shè)、成都外貿(mào)網(wǎng)站建設(shè)、高端網(wǎng)站制作、響應(yīng)式網(wǎng)頁設(shè)計(jì)等建站業(yè)務(wù),價(jià)格優(yōu)惠性價(jià)比高,為元寶等各大城市提供網(wǎng)站開發(fā)制作服務(wù)。
谷歌資深軟件工程師羅布·派克(Rob Pike)表示,“Go讓我體驗(yàn)到了從未有過的開發(fā)效率。”派克表示,和今天的C++或C一樣,Go是一種系統(tǒng)語言。他解釋道,“使用它可以進(jìn)行快速開發(fā),同時(shí)它還是一個真正的編譯語言,我們之所以現(xiàn)在將其開源,原因是我們認(rèn)為它已經(jīng)非常有用和強(qiáng)大。”
2007年,谷歌把Go作為一個20%項(xiàng)目開始研發(fā),即讓員工抽出本職工作之外時(shí)間的20%,投入在該項(xiàng)目上。除了派克外,該項(xiàng)目的成員還有其它一些谷歌工程師。
派克表示,編譯后Go代碼的運(yùn)行速度與C語言非常接近,而且編譯速度非常快,就像在使用一個交互式語言。
現(xiàn)有編程語言均未專門對多核處理器進(jìn)行優(yōu)化。派克表示,Go就是谷歌工程師為這類程序編寫的一種語言。它不是針對編程初學(xué)者設(shè)計(jì)的,但學(xué)習(xí)使用它也不是非常困難。Go支持面向?qū)ο螅揖哂姓嬲姆庋b(closures)和反射(reflection)等功能。
在學(xué)習(xí)曲線方面,派克認(rèn)為Go與Java類似,對于Java開發(fā)者來說,應(yīng)該能夠輕松學(xué)會Go。
之所以將Go作為一個開源項(xiàng)目發(fā)布,目的是讓開源社區(qū)有機(jī)會創(chuàng)建更好的工具來使用該語言,例如Eclipse IDE中的插件。目前還沒有支持Go的IDE。
在目前谷歌公開發(fā)布的所有網(wǎng)絡(luò)應(yīng)用中,均沒有使用Go。但是谷歌已經(jīng)使用該語言開發(fā)了幾個內(nèi)部項(xiàng)目。
派克表示,Go是否會對谷歌即將推出的Chrome OS產(chǎn)生影響,現(xiàn)在還言之尚早,不過Go的確可以和Native Client配合使用。他表示,“Go可以讓應(yīng)用完美的運(yùn)行在瀏覽器內(nèi)。”例如,使用Go可以更高效的實(shí)現(xiàn)Wave,無論是在前端還是后臺。
Go語言是一種新的語言,一種并發(fā)的、帶垃圾回收的、快速編譯的語言。它具有以下特點(diǎn):
1.它可以在一臺計(jì)算機(jī)上用幾秒鐘的時(shí)間編譯一個大型的Go程序。
2.Go語言為軟件構(gòu)造提供了一種模型,它使依賴分析更加容易,且避免了大部分C風(fēng)格include文件與庫的開頭。
3.Go語言是靜態(tài)類型的語言,它的類型系統(tǒng)沒有層級。因此用戶不需要在定義類型之間的關(guān)系上花費(fèi)時(shí)間,這樣感覺起來比典型的面向?qū)ο笳Z言更輕量級。
4.Go語言完全是垃圾回收型的語言,并為并發(fā)執(zhí)行與通信提供了基本的支持。
按照其設(shè)計(jì),Go打算為多核機(jī)器上系統(tǒng)軟件的構(gòu)造提供一種方法。
Go語言是一種編譯型語言,它結(jié)合了解釋型語言的游刃有余,動態(tài)類型語言的開發(fā)效率,以及靜態(tài)類型的安全性。它也打算成為現(xiàn)代的,支持網(wǎng)絡(luò)與多核計(jì)算的語言。要滿足這些目標(biāo),需要解決一些語言上的問題:一個富有表達(dá)能力但輕量級的類型系統(tǒng),并發(fā)與垃圾回收機(jī)制,嚴(yán)格的依賴規(guī)范等等。這些無法通過庫或工具解決好,因此Go也就應(yīng)運(yùn)而生了。
目錄
一、結(jié)構(gòu)體詳解
1. 結(jié)構(gòu)體定義
2. 實(shí)例化結(jié)構(gòu)體的7種方法
二、結(jié)構(gòu)體方法
1. 結(jié)構(gòu)體的方法定義
2. 結(jié)構(gòu)體內(nèi)自定義方法的引用
3. 任意類型添加方法
三、嵌套、繼承
1. 匿名結(jié)構(gòu)體
2. 結(jié)構(gòu)體中可以定義任意類型的字段
3. 結(jié)構(gòu)體嵌套結(jié)構(gòu)體
4. 結(jié)構(gòu)體嵌套匿名結(jié)構(gòu)體
5. 結(jié)構(gòu)體嵌套多個匿名結(jié)構(gòu)體
6. 結(jié)構(gòu)體繼承
四、結(jié)構(gòu)體和JSON相互轉(zhuǎn)換
1. 結(jié)構(gòu)體轉(zhuǎn)化成json
2. json轉(zhuǎn)化成結(jié)構(gòu)體
3. 結(jié)構(gòu)體標(biāo)簽 tag
4. 嵌套結(jié)構(gòu)體和json的序列化反序列化
Golang 中沒有“類”的概念,Golang 中的結(jié)構(gòu)體和其他語言中的類有點(diǎn)相似。和其他面向?qū)?象語言中的類相比,Golang 中的結(jié)構(gòu)體具有更高的擴(kuò)展性和靈活性。
Golang 中的基礎(chǔ)數(shù)據(jù)類型可以表示一些事物的基本屬性,但是當(dāng)我們想表達(dá)一個事物的全 部或部分屬性時(shí),這時(shí)候再用單一的基本數(shù)據(jù)類型就無法滿足需求了,Golang 提供了一種 自定義數(shù)據(jù)類型,可以封裝多個基本數(shù)據(jù)類型,這種數(shù)據(jù)類型叫結(jié)構(gòu)體,英文名稱 struct。 也就是我們可以通過 struct 來定義自己的類型了。
使用 type 和 struct 關(guān)鍵字來定義結(jié)構(gòu)體,具體代碼格式如下:
type 類型名 struct {
字段名 字段類型
字段名 字段類型 …
}
其中:
? 類型名:表示自定義結(jié)構(gòu)體的名稱,在同一個包內(nèi)不能重復(fù)。
? 字段名:表示結(jié)構(gòu)體字段名。結(jié)構(gòu)體中的字段名必須唯一。
? 字段類型:表示結(jié)構(gòu)體字段的具體類型。
在 go 語言中,沒有類的概念但是可以給類型(結(jié)構(gòu)體,自定義類型)定義方法。所謂方法 就是定義了接收者的函數(shù)。接收者的概念就類似于其他語言中的 this 或者 self。
方法的定義格式如下:
func (接收者變量 接收者類型) 方法名(參數(shù)列表) (返回參數(shù)) {
函數(shù)體
}
注意:想改變結(jié)構(gòu)體內(nèi)的值,必須先變成指針。
在 Go 語言中,接收者的類型可以是任何類型,不僅僅是結(jié)構(gòu)體,任何類型都可以擁有方法。 舉個例子,我們基于內(nèi)置的 int 類型使用 type 關(guān)鍵字可以定義新的自定義類型,然后為我們 的自定義類型添加方法。
注意:匿名結(jié)構(gòu)體中不允許出現(xiàn)多個重復(fù)的類型
注意:如果結(jié)構(gòu)體里面有私有屬性也就是小寫定義的字段,則不會被json使用
前言
最近工作中遇到的一個場景,php項(xiàng)目中需要使用一個第三方的功能,而恰好有一個用Golang寫好的類庫。那么問題就來了,要如何實(shí)現(xiàn)不同語言之間的通信呢?下面就來一起看看吧。
常規(guī)的方案
1、 用Golang寫一個http/TCP服務(wù),php通過http/TCP與Golang通信
2、將Golang經(jīng)過較多封裝,做為php擴(kuò)展。
3、PHP通過系統(tǒng)命令,調(diào)取Golang的可執(zhí)行文件
存在的問題
1、http請求,網(wǎng)絡(luò)I/O將會消耗大量時(shí)間
2、需要封裝大量代碼
3、PHP每調(diào)取一次Golang程序,就需要一次初始化,時(shí)間消耗很多
優(yōu)化目標(biāo)
1、Golang程序只初始化一次(因?yàn)槌跏蓟芎臅r(shí))
2、所有請求不需要走網(wǎng)絡(luò)
3、盡量不大量修改代碼
解決方案
1、簡單的Golang封裝,將第三方類庫編譯生成為一個可執(zhí)行文件
2、PHP與Golang通過雙向管道通信
使用雙向管道通信優(yōu)勢
1:只需要對原有Golang類庫進(jìn)行很少的封裝
2:性能最佳 (IPC通信是進(jìn)程間通信的最佳途徑)
3:不需要走網(wǎng)絡(luò)請求,節(jié)約大量時(shí)間
4:程序只需初始化一次,并一直保持在內(nèi)存中
具體實(shí)現(xiàn)步驟
1:類庫中的原始調(diào)取demo
package main
import (
"fmt"
"github.com/yanyiwu/gojieba"
"strings"
)
func main() {
x := gojieba.NewJieba()
defer x.Free()
s := "小明碩士畢業(yè)于中國科學(xué)院計(jì)算所,后在日本京都大學(xué)深造"
words := x.CutForSearch(s, true)
fmt.Println(strings.Join(words, "/"))
}
保存文件為main.go,就可以運(yùn)行
2:調(diào)整后代碼為:
package main
import (
"bufio"
"fmt"
"github.com/yanyiwu/gojieba"
"io"
"os"
"strings"
)
func main() {
x := gojieba.NewJieba(
"/data/tmp/jiebaDict/jieba.dict.utf8",
"/data/tmp/jiebaDict/hmm_model.utf8",
"/data/tmp/jiebaDict/user.dict.utf8"
)
defer x.Free()
inputReader := bufio.NewReader(os.Stdin)
for {
s, err := inputReader.ReadString('\n')
if err != nil err == io.EOF {
break
}
s = strings.TrimSpace(s)
if s != "" {
words := x.CutForSearch(s, true)
fmt.Println(strings.Join(words, " "))
} else {
fmt.Println("get empty \n")
}
}
}
只需要簡單的幾行調(diào)整,即可實(shí)現(xiàn):從標(biāo)準(zhǔn)輸入接收字符串,經(jīng)過分詞再輸出
測試:
# go build test
# ./test
# //等待用戶輸入,輸入”這是一個測試“
# 這是 一個 測試 //程序
3:使用cat與Golang通信做簡單測試
//準(zhǔn)備一個title.txt,每行是一句文本
# cat title.txt | ./test
正常輸出,表示cat已經(jīng)可以和Golang正常交互了
4:PHP與Golang通信
以上所示的cat與Golang通信,使用的是單向管道。即:只能從cat向Golang傳入數(shù)據(jù),Golang輸出的數(shù)據(jù)并沒有傳回給cat,而是直接輸出到屏幕。但文中的需求是:php與Golang通信。即php要傳數(shù)據(jù)給Golang,同時(shí)Golang也必須把執(zhí)行結(jié)果返回給php。因此,需要引入雙向管道。
在PHP中管道的使用:popen("/path/test") ,具體就不展開說了,因?yàn)榇朔椒ń鉀Q不了文中的問題。
雙向管道:
$descriptorspec = array(
0 = array("pipe", "r"),
1 = array("pipe", "w")
);
$handle = proc_open(
'/webroot/go/src/test/test',
$descriptorspec,
$pipes
);
fwrite($pipes['0'], "這是一個測試文本\n");
echo fgets($pipes[1]);
解釋:使用proc_open打開一個進(jìn)程,調(diào)用Golang程序。同時(shí)返回一個雙向管道pipes數(shù)組,php向$pipe['0']中寫數(shù)據(jù),從$pipe['1']中讀數(shù)據(jù)。
好吧,也許你已經(jīng)發(fā)現(xiàn),我是標(biāo)題檔,這里重點(diǎn)要講的并不只是PHP與Golang如何通信。而是在介紹一種方法: 通過雙向管道讓任意語言通信。(所有語言都會實(shí)現(xiàn)管道相關(guān)內(nèi)容)
測試:
通過對比測試,計(jì)算出各個流程占用的時(shí)間。下面提到的title.txt文件,包含100萬行文本,每行文本是從b2b平臺取的商品標(biāo)題
1: 整體流程耗時(shí)
time cat title.txt | ./test /dev/null
耗時(shí):14.819秒,消耗時(shí)間包含:
進(jìn)程cat讀出文本
通過管道將數(shù)據(jù)傳入Golang
Golang處理數(shù)據(jù),將結(jié)果返回到屏幕
2:計(jì)算分詞函數(shù)耗時(shí)。方案:去除分詞函數(shù)的調(diào)取,即:注釋掉Golang源代碼中的調(diào)取分詞那行的代碼
time cat title.txt | ./test /dev/null
耗時(shí):1.817秒時(shí)間,消耗時(shí)間包含:
進(jìn)程cat讀出文本
通過管道將數(shù)據(jù)傳入Golang
Golang處理數(shù)據(jù),將結(jié)果返回到屏幕
分詞耗時(shí) = (第一步耗時(shí)) - (以上命令所耗時(shí))
分詞耗時(shí) : 14.819 - 1.817 = 13.002秒
3:測試cat進(jìn)程與Golang進(jìn)程之間通信所占時(shí)間
time cat title.txt /dev/null
耗時(shí):0.015秒,消耗時(shí)間包含:
進(jìn)程cat讀出文本
通過管道將數(shù)據(jù)傳入Golang
go處理數(shù)據(jù),將結(jié)果返回到屏幕
管道通信耗時(shí):(第二步耗時(shí)) - (第三步耗時(shí))
管道通信耗時(shí): 1.817 - 0.015 = 1.802秒
4:PHP與Golang通信的時(shí)間消耗
編寫簡單的php文件:
?php
$descriptorspec = array(
0 = array("pipe", "r"),
1 = array("pipe", "w")
);
$handle = proc_open(
'/webroot/go/src/test/test',
$descriptorspec,
$pipes
);
$fp = fopen("title.txt", "rb");
while (!feof($fp)) {
fwrite($pipes['0'], trim(fgets($fp))."\n");
echo fgets($pipes[1]);
}
fclose($pipes['0']);
fclose($pipes['1']);
proc_close($handle);
流程與上面基本一致,讀出title.txt內(nèi)容,通過雙向管道傳入Golang進(jìn)程分詞后,再返回給php (比上面的測試多一步:數(shù)據(jù)再通過管道返回)
time php popen.php /dev/null
耗時(shí):24.037秒,消耗時(shí)間包含:
進(jìn)程PHP讀出文本
通過管道將數(shù)據(jù)傳入Golang
Golang處理數(shù)據(jù)
Golang將返回結(jié)果再寫入管道,PHP通過管道接收數(shù)據(jù)
將結(jié)果返回到屏幕
結(jié)論:
1 :整個分詞過程中的耗時(shí)分布
使用cat控制邏輯耗時(shí): 14.819 秒
使用PHP控制邏輯耗時(shí): 24.037 秒(比cat多一次管道通信)
單向管道通信耗時(shí): 1.8 秒
Golang中的分詞函數(shù)耗時(shí): 13.002 秒
2:分詞函數(shù)的性能: 單進(jìn)程,100萬商品標(biāo)題分詞,耗時(shí)13秒
以上時(shí)間只包括分詞時(shí)間,不包括詞典載入時(shí)間。但在本方案中,詞典只載入一次,所以載入詞典時(shí)間可以忽略(1秒左右)
3:PHP比cat慢 (這結(jié)論有點(diǎn)多余了,呵呵)
語言層面慢: (24.037 - 1.8 - 14.819) / 14.819 = 50%
單進(jìn)程對比測試的話,應(yīng)該不會有哪個語言比cat更快。
相關(guān)問題:
1:以上Golang源碼中寫的是一個循環(huán),也就是會一直從管道中讀數(shù)據(jù)。那么存在一個問題:是不是php進(jìn)程結(jié)束后,Golang的進(jìn)程還會一直存在?
管道機(jī)制自身可解決此問題。管道提供兩個接口:讀、寫。當(dāng)寫進(jìn)程結(jié)束或者意外掛掉時(shí),讀進(jìn)程也會報(bào)錯,以上Golang源代碼中的err邏輯就會執(zhí)行,Golang進(jìn)程結(jié)束。
但如果PHP進(jìn)程沒有結(jié)束,只是暫時(shí)沒有數(shù)據(jù)傳入,此時(shí)Golang進(jìn)程會一直等待。直到php結(jié)束后,Golang進(jìn)程才會自動結(jié)束。
2:能否多個php進(jìn)程并行讀寫同一個管道,Golang進(jìn)程同時(shí)為其服務(wù)?
不可以。管道是單向的,如果多個進(jìn)程同時(shí)向管道中寫,那Golang的返回值就會錯亂。
可以多開幾個Golang進(jìn)程實(shí)現(xiàn),每個php進(jìn)程對應(yīng)一個Golang進(jìn)程。
最后,上面都是瞎扯的。如果你了解管道、雙向管道,上面的解釋對你基本沒啥用。但如果你不了解管道,調(diào)試上面的代碼沒問題,但稍有修改就有可能掉坑里。
網(wǎng)頁題目:GO語言封裝工能的用處的簡單介紹
當(dāng)前路徑:http://chinadenli.net/article33/dsidiss.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供標(biāo)簽優(yōu)化、網(wǎng)站導(dǎo)航、營銷型網(wǎng)站建設(shè)、網(wǎng)站建設(shè)、品牌網(wǎng)站設(shè)計(jì)、網(wǎng)頁設(shè)計(jì)公司
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)