Go 由于不支持泛型而臭名昭著,但最近,泛型已接近成為現(xiàn)實(shí)。Go 團(tuán)隊(duì)實(shí)施了一個看起來比較穩(wěn)定的設(shè)計(jì)草案,并且正以源到源翻譯器原型的形式獲得關(guān)注。本文講述的是泛型的最新設(shè)計(jì),以及如何自己嘗試泛型。
為福海等地區(qū)用戶提供了全套網(wǎng)頁設(shè)計(jì)制作服務(wù),及福海網(wǎng)站建設(shè)行業(yè)解決方案。主營業(yè)務(wù)為成都做網(wǎng)站、成都網(wǎng)站設(shè)計(jì)、成都外貿(mào)網(wǎng)站建設(shè)、福海網(wǎng)站設(shè)計(jì),以傳統(tǒng)方式定制建設(shè)網(wǎng)站,并提供域名空間備案等一條龍服務(wù),秉承以專業(yè)、用心的態(tài)度為用戶提供真誠的服務(wù)。我們深信只要達(dá)到每一位用戶的要求,就會得到認(rèn)可,從而選擇與我們長期合作。這樣,我們也可以走得更遠(yuǎn)!
例子
FIFO Stack
假設(shè)你要創(chuàng)建一個先進(jìn)先出堆棧。沒有泛型,你可能會這樣實(shí)現(xiàn):
type?Stack?[]interface{}func?(s?Stack)?Peek()?interface{}?{
return?s[len(s)-1]
}
func?(s?*Stack)?Pop()?{
*s?=?(*s)[:
len(*s)-1]
}
func?(s?*Stack)?Push(value?interface{})?{
*s?=?
append(*s,?value)
}
但是,這里存在一個問題:每當(dāng)你 Peek 項(xiàng)時,都必須使用類型斷言將其從 interface{} 轉(zhuǎn)換為你需要的類型。如果你的堆棧是 *MyObject 的堆棧,則意味著很多 s.Peek().(*MyObject)這樣的代碼。這不僅讓人眼花繚亂,而且還可能引發(fā)錯誤。比如忘記 * 怎么辦?或者如果您輸入錯誤的類型怎么辦?s.Push(MyObject{})` 可以順利編譯,而且你可能不會發(fā)現(xiàn)到自己的錯誤,直到它影響到你的整個服務(wù)為止。
通常,使用 interface{} 是相對危險的。使用更多受限制的類型總是更安全,因?yàn)榭梢栽诰幾g時而不是運(yùn)行時發(fā)現(xiàn)問題。
泛型通過允許類型具有類型參數(shù)來解決此問題:
type?Stack(type?T)?[]Tfunc?(s?Stack(T))?Peek()?T?{
return?s[len(s)-1]
}
func?(s?*Stack(T))?Pop()?{
*s?=?(*s)[:
len(*s)-1]
}
func?(s?*Stack(T))?Push(value?T)?{
*s?=?
append(*s,?value)
}
這會向 Stack 添加一個類型參數(shù),從而完全不需要 interface{}。現(xiàn)在,當(dāng)你使用 Peek() 時,返回的值已經(jīng)是原始類型,并且沒有機(jī)會返回錯誤的值類型。這種方式更安全,更容易使用。(譯注:就是看起來更丑陋,^-^)
此外,泛型代碼通常更易于編譯器優(yōu)化,從而獲得更好的性能(以二進(jìn)制大小為代價)。如果我們對上面的非泛型代碼和泛型代碼進(jìn)行基準(zhǔn)測試,我們可以看到區(qū)別:
type?MyObject?struct?{
X?
int
}
var?sink?MyObjectfunc?BenchmarkGo1(b?*testing.B)?{
for?i?:=?0;?i??b.N;?i++?{
var?s?Stack
s.Push(MyObject{})
s.Push(MyObject{})
s.Pop()
sink?=?s.Peek().(MyObject)
}
}
func?BenchmarkGo2(b?*testing.B)?{
for?i?:=?0;?i??b.N;?i++?{
var?s?Stack(MyObject)
s.Push(MyObject{})
s.Push(MyObject{})
s.Pop()
sink?=?s.Peek()
}
}
結(jié)果:
BenchmarkGo1BenchmarkGo1-16?????12837528?????????87.0?ns/op???????48?B/op????????2?allocs/opBenchmarkGo2BenchmarkGo2-16?????28406479?????????41.9?ns/op???????24?B/op????????2?allocs/op
在這種情況下,我們分配更少的內(nèi)存,同時泛型的速度是非泛型的兩倍。
合約(Contracts)
上面的堆棧示例適用于任何類型。但是,在許多情況下,你需要編寫僅適用于具有某些特征的類型的代碼。例如,你可能希望堆棧要求類型實(shí)現(xiàn) String() 函數(shù)
前段時間使用docker搭建了一個wiki的網(wǎng)站,用于記錄日常學(xué)習(xí)中的筆記,用了一段時間,功能很強(qiáng)大,但是編輯器不太熟悉,網(wǎng)站使用java開發(fā)的,功能很全面,插件多的時候就感覺越來越臃腫。曾經(jīng)有段時間就不想使用它了,最近偶然發(fā)現(xiàn)一個靜態(tài)網(wǎng)站的生成工具h(yuǎn)ugo,可以將markdown直接生成網(wǎng)站,部署到站點(diǎn)上作為自己的知識庫或者博客,hugo是使用go語言開發(fā)的,使用起來非常方便,生成的網(wǎng)站可直接部署在Nginx、IIS等中間件上面供其他人訪問,hugo還有很多漂亮的主題,大家可以選擇自己喜歡的進(jìn)行使用,下面介紹下 我安裝使用hugo的經(jīng)歷和方法。
1)使用brew install命令安裝
我的電腦是mac的,所以最方便的是直接用brew install hugo命令安裝最為方便:
執(zhí)行安裝完成后執(zhí)行hugo version 命令查看版本,確保安裝成功
2)下載二進(jìn)制包:解壓后將二進(jìn)制文件加入環(huán)境變量的方式安裝。大家可以根據(jù)自己的操作系統(tǒng),下載適合的安裝包。
3)也可以下載源碼 編譯 運(yùn)行,由于我本地的go版本是1.17的,而hugo的最新代碼的最低要求是1.18,暫時還不想升級,所以源碼編譯的方式這里就不過多介紹,感興趣的可以下載源碼編譯試試。
進(jìn)入要創(chuàng)建網(wǎng)站的目錄,執(zhí)行一下命令
這樣名稱為test-blog的網(wǎng)站就建好了 ,
下載一個主題 可以在 官網(wǎng)上找到各種各樣的主題
將主體添加至配置文件
打開content/posts目錄下的index.md 文件進(jìn)行編輯,頁面的配置項(xiàng)說明參見官網(wǎng)
執(zhí)行下面命令
成功以后就可以訪問就可以訪問網(wǎng)站了。
執(zhí)行命令hugo -D 即可生成一個public的文件夾,其下面的內(nèi)容即為靜態(tài)網(wǎng)站的所有文件
這里使用nginx的docker鏡像 進(jìn)行部署,執(zhí)行以下命令:
執(zhí)行成功后就能通過http:localhost訪問到靜態(tài)網(wǎng)站了。
這個工具還有很多需要研究的地方,這里只是將簡單的使用方法記錄了一下,以后怎樣使用才能使網(wǎng)站更加的方便,快捷、美觀,還要花時間研究。有興趣的小伙伴可以私信我一塊研究。
從2013年起,經(jīng)朋友推薦開始用Golang編寫游戲登陸服務(wù)器, 配合C++做第三方平臺驗(yàn)證. 到編寫?yīng)毩⒐ぞ邔?dǎo)表工具GitHub - davyxu/tabtoy: 跨平臺的高性能便捷電子表格導(dǎo)出器. 以及網(wǎng)絡(luò)庫GitHub - davyxu/cellnet: 簡單,方便,高效的Go語言的游戲服務(wù)器底層. 最終使用這些工具及庫編寫整個游戲服務(wù)器框架, 我的感受是很不錯的
細(xì)節(jié)看來, 有如下的幾個點(diǎn):
語言, 庫
Golang語言特性和C很像, 簡單, 一張A4紙就能寫完所有特性. 你想想看, C++到了領(lǐng)悟階段, 也只用那幾個簡單特性, 剩下的都是一大堆解決各種內(nèi)存問題的技巧. 而Golang一開始就簡單, 何必浪費(fèi)生命去研究那一大堆的奇技淫巧呢?
Golang的坑只有2個:1. interface{}和nil配合使用, 2. for循環(huán)時, 將循環(huán)變量引入閉包(Golang, Lua, C#閉包變量捕獲差異) 完全不影響正常使用, 復(fù)合語言概念, 只是看官方后面怎么有效的避免
用Golang就忘記繼承那套東西, 用組合+接口
用Golang服務(wù)器如何保證解決游戲服務(wù)器存盤一致性問題? stop the world是肯定的, 但是Golang可以從語言層并發(fā)序列化玩家數(shù)據(jù), 再通過后臺存盤
channel是goroutine雖然是Golang的語言特性. 但是在編寫服務(wù)器時, 其實(shí)只有底層用的比較多.
Golang的第三方庫簡直多如牛毛, 好的也很多
不要說模板了, C#的也不好用, 官方在糾結(jié)也不要加, 使用中, 沒模板確實(shí)有點(diǎn)不方便. 用interface{}/反射做泛型對于Golang這種強(qiáng)類型語言來說,還是有點(diǎn)打臉
運(yùn)行期
Golang和C++比性能的話, 這是C++的優(yōu)勢, Golang因?yàn)闆]虛擬機(jī), 只有薄薄的一層調(diào)度層. 因此性能是非常高的, 用一點(diǎn)性能犧牲換開發(fā)效率, 妥妥的
1.6版后的GC優(yōu)化的已經(jīng)很好了, 如果你不是高性能,高并發(fā)Web應(yīng)用, 非要找出一堆的優(yōu)化技巧的話. 只用Golang寫點(diǎn)游戲服務(wù)器, 那點(diǎn)GC損耗可以忽略不計(jì)
和其他現(xiàn)代語言一樣, 崩潰捕捉是標(biāo)配功能, 我用Golang的服務(wù)器線上跑, 基本沒碰到過崩潰情況
熱更新: 官方已經(jīng)有plugin系統(tǒng)的提交, 跨平臺的. 估計(jì)很快就可以告別手動cgo做so熱更新
開發(fā), 調(diào)試, 部署, 優(yōu)化
LiteIDE是我首選的Golang的IDE, 雖然有童鞋說B格不高. 但這估計(jì)實(shí)在是找不到缺點(diǎn)說了, 別跟我說Visual Studio, 那是宇宙級的...
曾經(jīng)聽說有人不看好Golang, 我問為啥: 說這么新的語言, 不好招人,后面打聽到他是個策劃... 好吧
真實(shí)情況是這樣的: Golang對于有點(diǎn)編程基礎(chǔ)的新人來說, 1周左右可以開始貢獻(xiàn)代碼. 老司機(jī)2~3天.
開發(fā)效率還是不錯的, 一般大的游戲功能, 2*2人一周3~4個整完. 這換C++時代, 大概也就1~2個還寫不完. 對接服務(wù)器sdk的話, 大概1天接個10多個沒問題
Golang自帶性能調(diào)優(yōu)工具, 從內(nèi)存, CPU, 阻塞點(diǎn)等幾個方面直接出圖進(jìn)行分析, 非常直觀, 可以參考我博客幾年前的分析: 使用Golang進(jìn)行性能分析(Profiling)
Golang支持交叉編譯, 跨平臺部署, 什么概念? linux是吧? 不問你什么版本, 直接windows上編譯輸出一個elf, 甩到服務(wù)器上開跑.不超過1分鐘時間..
這選擇顯然是因人而異的。。至于怎么選,要看你是初學(xué)者,還是老手?。。對性能有要求,還是沒要求?
如果是完全沒有基礎(chǔ),我建議哪個都不選,如果非要選一個,那就選PYTHON。。如果你是初學(xué)者,把網(wǎng)上的教程看個遍,再買上幾本書。。。你所學(xué)會的也僅僅是語法,而根本不會編程。。。因?yàn)檫@些教程,也僅僅是教你語法,而沒有教你編程。。你甚至把網(wǎng)上的教程看個精光,卻連個最基本的OA系統(tǒng)都做不出來。。。只能在一個黑乎乎的控制臺上,打印一堆破字符。。
-------網(wǎng)上的所有教程都會教你的:
怎么定義一個變量?怎么在控制臺打印變量?
怎么寫一個循環(huán)?怎么在控制臺打印一堆變量?
怎么寫一個函數(shù)?怎么在控制臺打印返回值?
怎么創(chuàng)建一個對象?怎么在控制臺打印對象屬性?
------高級一點(diǎn)的教程,會教你的:
怎么用PYTHON的模塊,寫一個爬蟲?
怎么用RUBY的ROR框架,獲取一個表單?
怎么用GO的beego,寫一個博客?
-------而這些的教程,從來不教你的:
面向?qū)ο笥惺裁从茫?委托是什么?事件是什么? 工廠模式,單例模式,觀察者模式,這些都是啥?套接字是啥?UDP是啥?TCP/IP是啥?二叉樹是什么玩意?狀態(tài)機(jī)又是什么玩意?啥叫逆變?啥叫協(xié)變?啥叫異步?啥叫反射?
---------------------------------------------------------------------------------------------
如果一套教程,要把這些都講明白。。。可能需要上千集。。。所以這些教程,都跳過了這些內(nèi)容。。但如果你不明白這些,就根本學(xué)不會編程。。。如果你打算學(xué)一門語言,而手上只有幾十集教程,外加三五本書。。。那你只能學(xué)會玩控制臺。。。
所以初學(xué)者選擇一門語言,首先要保證這門語言作為主要開發(fā)語言,常年被公司使用,這樣才能真正學(xué)會編程。然而這三門語言都不具備這樣的特點(diǎn)。它們通常都是被當(dāng)成第二語言,做一些輔助開發(fā)的工作。其中Python只在極少數(shù)情況下,才被用來作為主要開發(fā)語言。至于Go與Ruby,我目前還沒聽說過它們有被當(dāng)作主要開發(fā)語言的例子。我所推薦的是從C#和JAVA兩者之間,二選一。。。學(xué)精其中一門之后,再來考慮PYTHON或GO作為第二語言。。。不然無論你選哪個,都幾乎不可能靠一門語言找到工作。
現(xiàn)在個人博客通常有比較多的選擇,如果不想要自己購買服務(wù)器實(shí)現(xiàn)靜態(tài)博客的發(fā)布,可以在、CSDN等平臺建立自己的賬號并發(fā)布,但是原始數(shù)據(jù)無法在本地管理;如果想要數(shù)據(jù)完全自己管理,可以使用GitHub或者Gitee Pages功能發(fā)布自己的博客,利用Hugo或Hexo等成熟的靜態(tài)博客將md文件轉(zhuǎn)換成靜態(tài)網(wǎng)站文件進(jìn)行快速發(fā)布。本文就用來記錄如何快速將博客發(fā)布到、GitHub以及Gitee Pages三個平臺。
我希望的流程當(dāng)然是主要精力用在寫文章,發(fā)布的流程最好完全不需要手動處理,但實(shí)際情況下手動發(fā)布博客的流程大體是:
之前有使用過Travis CI+GitHub+Hexo自動發(fā)布到GitHub Pages,但是GitHub的訪問經(jīng)常不那么靠譜,因此想著也能同步到Gitee,并且自動構(gòu)建Hexo的速度受Nodejs環(huán)境部署影響,速度很慢,因此本次計(jì)劃采用Hugo來構(gòu)建網(wǎng)站文件,整體流程設(shè)計(jì)如下:
為了滿足博客自動發(fā)布流程,首先需要在本地準(zhǔn)備好生產(chǎn)環(huán)境,以滿足快速發(fā)布,以此的復(fù)雜是為了長期的簡單,因此在環(huán)境準(zhǔn)備階段我會把所有涉及的工具都記錄下來,以方便大家使用以及后邊自己回顧,環(huán)境準(zhǔn)備包含:
Obsidian完成知識積累后,按照ZK-Project-Archive-Blog的流程發(fā)布Blog,但是Obsidian的文件相互關(guān)聯(lián),且附件如何快速復(fù)用,需要對Typora和Obsidian都進(jìn)行簡單的配置,確保后續(xù)Blog能夠快速完成并發(fā)布,并且文件仍在Obsidian工程中正常顯示;
Typora非常的簡潔,而且可以實(shí)時預(yù)覽,在寫博客的時候經(jīng)常會插入一些圖片,截圖后可以直接粘貼進(jìn)去,圖片也會自動保存在本地,這里需要注意圖片的保存路徑,在偏好設(shè)置里,設(shè)置插入圖片時復(fù)制到指定路徑(./resource/),這樣復(fù)制的圖片就會自動保存在當(dāng)前文件夾下的resource文件夾里,方便后續(xù)管理與轉(zhuǎn)移。
在.ssh文件生成id_rsa和id_rsa.pub兩個文件;
Hugo 是一個基于Go語言開發(fā)的靜態(tài)博客框架,號稱世界上最快的構(gòu)建網(wǎng)站工具;
命令為: hugo new site myblog
myblog為博客的目錄名,可以修改為你自己想取的名字,生成的目錄如下:
由于默認(rèn)主題生成的文章頁面有些功能是不需要的,因此需要對themes下文件進(jìn)行修改:
將config、content和themes三個目錄拷貝到新創(chuàng)建的站點(diǎn)目錄,將content下替換為文章文件即可。
utterances 是一款基于Github Issue的Github工具,優(yōu)點(diǎn)主要是無廣告、加載快、配置簡單,輕量開源。
由于 utterances 是一款Github App,因此 安裝utterances 非常簡單,只需要授權(quán)特定repo權(quán)限給 utterances 就可以了,注意一個點(diǎn):授權(quán)的這個repo必須是public的,可以選擇多個repo,但是建議選擇一個就可以了,也比較安全。
這是當(dāng)前最簡單的配置方法, 也可以在 utterances官方 查看其他配置方法,以及詳細(xì)的配置參數(shù)說明。
Obsidian的安裝和使用可參考我的另一篇文章: Obsidian作為第二大腦工具的基本使用和配置
所有環(huán)境準(zhǔn)備好后,終于要開始啟動我們的自動化流程的實(shí)現(xiàn)了;
同之前步驟相同,將Gitee密碼配置到GitHub Secrets,命名為:GITEE_PASSWORD,所有配置結(jié)果如下:
synctogitee.yml
需要綁定Gitee賬號到微信公眾號,否則最后一步reload pages自動部署Gitee Pages會登錄失敗,原因是需要短信驗(yàn)證;綁定公眾號后則不需要短信驗(yàn)證;其他問題解決可以參考 gitee-pages-action
在Typora完成文章編寫后,一鍵上傳所有圖片到Gitee圖床,拷貝發(fā)布到,然后提交到GitHub repo master分支,即可自動部署到GitHub和Gitee Pages;
以上就是我利用GitHub-Actions將Hugo博客自動發(fā)布到GitHub和Gitee Pages,希望可以幫助大家快速構(gòu)建自己的個人網(wǎng)站;后邊我會繼續(xù)完善我的第二大腦系統(tǒng)的構(gòu)建思路和方法。
近期正在探索前端、后端、系統(tǒng)端各類常用組件與工具,對其一些常見的組件進(jìn)行再次整理一下,形成標(biāo)準(zhǔn)化組件專題,后續(xù)該專題將包含各類語言中的一些常用組件。歡迎大家進(jìn)行持續(xù)關(guān)注。
本節(jié)分享一個基于Go語言的HTML和CSS網(wǎng)站生成器 hugo ,它針對速度、易用性和可配置性進(jìn)行了優(yōu)化。Hugo 獲取一個包含內(nèi)容和模板的目錄,并將它們呈現(xiàn)為一個完整的 HTML 網(wǎng)站。Hugo 依賴于 Markdown 文件和元數(shù)據(jù)的前端,你可以從任何目錄運(yùn)行 Hugo。這適用于您沒有特權(quán)帳戶的共享主機(jī)和其他系統(tǒng)。例如我們?nèi)粘>帉懸恍┎┛臀恼拢M(jìn)行快速生成一套靜態(tài)頁面進(jìn)行分享時可以使用它來進(jìn)行生成一套靜態(tài)頁面作為我們的博客部署基礎(chǔ)。
它支持大量的主題模板,我們可以通過 進(jìn)行選擇相關(guān)的主題使用,有興趣的小伙伴可以進(jìn)行深入研究一下
文章標(biāo)題:go語言開發(fā)博客,go語言開發(fā)博客網(wǎng)
當(dāng)前網(wǎng)址:http://chinadenli.net/article22/hecccc.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供關(guān)鍵詞優(yōu)化、網(wǎng)頁設(shè)計(jì)公司、python、企業(yè)建站、微信公眾號、網(wǎng)站設(shè)計(jì)公司
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)