go語言的模式匹配 go語言比較

go語言的reflect(反射)

1、反射可以在運(yùn)行時 動態(tài)獲取變量的各種信息 ,比如變量的類型、類別;

10年積累的網(wǎng)站制作、成都網(wǎng)站設(shè)計經(jīng)驗(yàn),可以快速應(yīng)對客戶對網(wǎng)站的新想法和需求。提供各種問題對應(yīng)的解決方案。讓選擇我們的客戶得到更好、更有力的網(wǎng)絡(luò)服務(wù)。我雖然不認(rèn)識你,你也不認(rèn)識我。但先網(wǎng)站設(shè)計后付款的網(wǎng)站建設(shè)流程,更有青山免費(fèi)網(wǎng)站建設(shè)讓你可以放心的選擇與我們合作。

2、如果是結(jié)構(gòu)體變量,還可以獲取到結(jié)構(gòu)體本身的信息(包括結(jié)構(gòu)體的字段、方法);

3、通過反射,可以修改 變量的值 ,可以調(diào)用關(guān)聯(lián)的方法;

4、使用反射,需要import " reflect ".

5、示意圖:

1、不知道接口調(diào)用哪個函數(shù),根據(jù)傳入?yún)?shù)在運(yùn)行時確定調(diào)用的具體接口,這種需要對函數(shù)或方法反射。

例如以下這種橋接模式:

示例第一個參數(shù)funcPtr以接口的形式傳入函數(shù)指針,函數(shù)參數(shù)args以可變參數(shù)的形式傳入,bridge函數(shù)中可以用反射來動態(tài)執(zhí)行funcPtr函數(shù)。

1、reflect.TypeOf(變量名),獲取變量的類型,返回reflect.Type類型。

2、reflect.ValueOf(變量名),獲取變量的值,返回reflect.Value類型reflect.Value是一個結(jié)構(gòu)體類型。

3、變量、interface{}和reflect.Value是可以互相轉(zhuǎn)換的,這點(diǎn)在實(shí)際開發(fā)中,會經(jīng)常使用到。

1、reflect.Value.Kind,獲取變量的 類別(Kind) ,返回的是一個 常量 。在go語言文檔中:

示例如下所示:

輸出如下:

Kind的范疇要比Type大。比如有Student和Consumer兩個結(jié)構(gòu)體,他們的 Type 分別是 Student 和 Consumer ,但是它們的 Kind 都是 struct 。

2、Type是類型,Kind是類別,Type和Kind可能是相同的,也可能是不同的。

3、通過反射可以在讓 變量 在 interface{} 和 Reflect.Value 之間相互轉(zhuǎn)換,這點(diǎn)在前面畫過示意圖。

4、使用反射的方式來獲取變量的值(并返回對應(yīng)的類型),要求數(shù)據(jù)類型匹配,比如x是int,那么久應(yīng)該使用reflect.Value(x).Int(),而不能使用其它的,否則報panic。

如果是x是float類型的話,也是要用reflect.Value(x).Float()。但是如果是struct類型的話,由于type并不確定,所以沒有相應(yīng)的方法,只能 斷言。

5、通過反射的來修改變量,注意當(dāng)使用SetXxx方法來設(shè)置需要通過對應(yīng)的指針類型來完成,這樣才能改變傳入的變量的值,同時需要使用到reflect.Value.Elem()方法。

輸出num=20,即成功使用反射來修改傳進(jìn)來變量的值。

6、reflect.Value.Elem()應(yīng)該如何理解?

現(xiàn)代編程語言那些讓人激動的特性

有沒有覺得,發(fā)展到現(xiàn)在,軟件開發(fā)行業(yè)是越來越成熟了,無論是過程管理、架構(gòu)方法、設(shè)計方法,還是語言、平臺、框架、工具等,都發(fā)展到了一個前所未有的高度,相關(guān)思想和理念也日臻完善,我們真正進(jìn)入了一個最好的時代。

單就編程語言來說,近些年包括Scala(2003)、Groovy(2003)、Go(2009)、Kotlin(2011)、Swift(2014)等新興編程語言如雨后春筍版涌現(xiàn)出來,也給我們帶來了很多讓人眼前一亮的編程特性,甚至Java這等老牌編程語言也是不斷推陳出新,編程再也不像過去那般枯燥。

本篇就帶大家一起感受一下現(xiàn)代編程語言那些激動人心的特性。

這個特性其實(shí)有點(diǎn)早了,但是也是很早就讓人感動的語言特性了,熟悉Javascript的同學(xué)應(yīng)該對它很了解。Javascript語言具有動態(tài)性,我們可以隨時為類的某個實(shí)例添加方法,也可以利用動態(tài)原型,為類的所有實(shí)例添加方法,有沒有感覺擴(kuò)展類的實(shí)現(xiàn)變得非常方便了呢?

擴(kuò)展和原型很像,允許我們在不修改或繼承類的情況下,將新的函數(shù)方法添加到原類中。這個特性較早見于C#這門語言,目前在Kotlin、Swift中均可以看到。這里順便說一下C#,當(dāng)時C#出來的時候,不得不說很多特性是非常棒的,包括擴(kuò)展方法、泛型、分部類等等,比Java好不要太多。像Kotlin,不僅可以擴(kuò)展類的方法,還可以擴(kuò)展類的屬性。

前兩個都是關(guān)于擴(kuò)展代碼的,這里再來一個。我們知道Java 1.8以來,接口interface里的方法可以有自己的默認(rèn)實(shí)現(xiàn)了,大大方便了實(shí)現(xiàn)類,減少了重復(fù)代碼。相對于Java的這個實(shí)現(xiàn)是顯示的,Go語言的接口實(shí)現(xiàn)可以是隱式的,添加隱式實(shí)現(xiàn)后,所有繼承的結(jié)構(gòu)(Go沒有類,都是結(jié)構(gòu)struct)都可以調(diào)用這個方法,和前面的兩個特性有異曲同工之妙,下面我們對比看一下。

C語言就有宏的概念,通過 #define 定義,然后在代碼中進(jìn)行替換。宏作為Rust語言的高級特性,可以操作語法單元,是一種通過編寫代碼來生成代碼的方式,被稱作“元編程”(meta programming)。相對于函數(shù),宏可以接受任意多個參數(shù),可以減少重復(fù)代碼,定義DSL。宏語法比較復(fù)雜,難以編寫和調(diào)試,以至于在Rust文檔中說,宏將是其最后的特性。

當(dāng)你回想寫代碼枯燥的時候,應(yīng)該會想到為字段編寫getter、setter吧?較早的時候,C#就意識到了這個問題,貼心地推出了自動屬性這個語法糖。而Java開發(fā)者則是通過Eclipse、IDEA這樣的開發(fā)工具來自動生成getter、setter代碼。當(dāng)然,現(xiàn)在也可以依賴Lombook包,使用lombok的注解@Getter @Setter來編譯時生成相關(guān)代碼。

據(jù)說空指針異常是軟件業(yè)最貴的異常,價值10億美元。你有沒有為處理調(diào)用鏈中的null值而煩惱過?又或者被傷害過?Kotlin會在編譯期提示對可能為null變量的不安全使用,也提供了Elvis 操作符 ?: 來方便地處理null值。而有了可選鏈,就舒服多了??蛇x鏈語法應(yīng)該較早出現(xiàn)在JavaScript語言中,新興語言Swift也提供了這一省心的特性。Swift英明地決定變量是不允許直接存儲NIL值,當(dāng)然也提供了optionals的裝箱功能允許將NIL或其它值包裝起來,方便有時使用。

輸入乃萬惡之源,函數(shù)首要的事情就是檢查不規(guī)范和不安全的輸入,這也是衛(wèi)語句的來歷。Swift語言為此提供了專門的衛(wèi)語句語法,有了它的貼身防護(hù),整個代碼都干爽多了,劇烈運(yùn)動都不怕,不信往下瞧:

如果要評選最酷的語言特性,那么Lambda表達(dá)式必須獲得提名。Lambda表達(dá)式很早就出現(xiàn)在Lisp語言中,python也有,在后來的C#語言大放異彩,又一次狠狠地羞辱了不長進(jìn)的Java,而Java也終于在1.8版本后加入了這一特性,甚至C++ 11也光榮地上車了。

我們知道編程語言有靜態(tài)和動態(tài)之分,靜態(tài)語言如Java 、 C# 、 C 和 C++,動態(tài)語言如Perl,Python,JavaScript,Ruby 和 PHP等,多數(shù)為腳本語言。而融合了靜態(tài)和動態(tài)特性的語音,就被稱為漸進(jìn)式語言,如TypeScript、Common LISP、Dylan、Cecil、Visual Basic.NET、Bigloo Scheme、Strongtalk等。靜態(tài)類型檢查可以盡早地發(fā)現(xiàn) BUG,動態(tài)類型檢查可以方便地處理依賴于運(yùn)行時信息的值的類型。 漸進(jìn)式語言允許類型注釋來控制程序的一部分使用靜態(tài)類型檢查,而另一部分為動態(tài)檢查,更具靈活性。 Python從3.5開始引入了對靜態(tài)類型檢查的支持。

在面向?qū)ο蟮木幊陶Z言中,狀態(tài)是計算的基礎(chǔ)。由于可變狀態(tài)的存在,在編寫高并發(fā),多線程代碼時,無法知道并行進(jìn)行的諸多狀態(tài)讀寫中是否有順序上的錯誤,而且這種錯誤又是難以察覺的,而不變性則規(guī)避了這個問題。 不變性是函數(shù)式編程的基礎(chǔ),不變性意味著函數(shù)沒有副作用,無論多少次執(zhí)行,相同的輸入就意味著相同的輸出,所有線程都可以無所顧忌的執(zhí)行同一個函數(shù)的代碼,代碼更像數(shù)學(xué)函數(shù),更易理解和測試。

String就是構(gòu)建在Java語言內(nèi)核中的不可變類的一個典型例子。Java 的 CopyOnWrite系列容器類也是利用了不變性增強(qiáng)了并發(fā)安全性。Java可以通過final修飾符實(shí)現(xiàn)類和變量的不可變。而Scala、Swift、Groovy等語言也有各自的語法實(shí)現(xiàn)不可變的變量和類。

多重分派是一些編程語言的特性,其中的函數(shù)或者方法,可以在運(yùn)行時間(動態(tài)的)使用一個或多個實(shí)際參數(shù)的組合特征,路由動態(tài)分派至實(shí)現(xiàn)函數(shù)或方法。多重分派主要區(qū)別于我們常見的重載方法,重載方法是在編譯期就綁定了,而多重分派是在運(yùn)行期分派的。Lisp、Julia、C#、Groovy等語言內(nèi)建多分派特性,JavaScript、Python和C等語言通過擴(kuò)展支持多分派。 多重分派可以避免我們寫很多分支條件,而是更直觀地用對象類型表達(dá),使代碼變得可讀性更好并且較少發(fā)生錯誤。

前面幾個特性是不是略顯沉悶,那么來看一下這個激動一下。解構(gòu)這一語法特性用于從數(shù)組索引或?qū)ο髮傩詣?chuàng)建變量,簡直帥到飛起。

愛寫單元測試的同學(xué)有福了,這個絕壁是重磅炸彈,在生產(chǎn)代碼里夾著測試代碼,你有想過這么寫測試嗎?誰想的?簡直腦洞打開??!該特性在Pyret語言中,Pyret旨在作為編程教育的杰出選擇,同時 探索 腳本和函數(shù)式編程的融合。

如果內(nèi)聯(lián)測試沒有讓你震驚,D語言內(nèi)聯(lián)編譯期的這個特性絕對會讓你驚掉下巴,基于該特性,開發(fā)人員可以直接在D語言中嵌入?yún)R編代碼,徹底放飛自我了,俺滴親娘啊!受不了!受不了!順便說一下,D語言比較小眾,是C++的一個改進(jìn)型,它包括了按合約設(shè)計、垃圾回收、關(guān)聯(lián)數(shù)組、數(shù)組切片和惰性求值等特性。

好吧,我們看點(diǎn)其它的來壓壓驚吧。盡管Kotlin語言也說自己實(shí)現(xiàn)了模式匹配,但是實(shí)際上只是一點(diǎn)點(diǎn)帥,真正帥的是 Elixir語言的模式匹配,Elixir作為一種在Erlang OTP上運(yùn)行的動態(tài)類型語言,將模式匹配提升到了一個全新的水平。

在編程語法上,Python真是個神一樣的存在,for循環(huán)都能寫出花來。

Java 8 中提供了Stream API特性, Stream 使用一種類似用 SQL 語句從數(shù)據(jù)庫查詢數(shù)據(jù)的直觀方式,來提供一種對 Java 集合運(yùn)算和表達(dá)的高階抽象。事實(shí)上這個特性C#早就有了(Java又躺槍一次)。不得不說,利用這個特性寫出來的代碼,看上去還真的是很流利的。

go語言可以做什么

1、服務(wù)器編程:以前你如果使用C或者C++做的那些事情,用Go來做很合適,例如處理日志、數(shù)據(jù)打包、虛擬機(jī)處理、文件系統(tǒng)等。

2、分布式系統(tǒng)、數(shù)據(jù)庫代理器、中間件:例如Etcd。

3、網(wǎng)絡(luò)編程:這一塊目前應(yīng)用最廣,包括Web應(yīng)用、API應(yīng)用、下載應(yīng)用,而且Go內(nèi)置的net/http包基本上把我們平常用到的網(wǎng)絡(luò)功能都實(shí)現(xiàn)了。

4、開發(fā)云平臺:目前國外很多云平臺在采用Go開發(fā),我們所熟知的七牛云、華為云等等都有使用Go進(jìn)行開發(fā)并且開源的成型的產(chǎn)品。

5、區(qū)塊鏈:目前有一種說法,技術(shù)從業(yè)人員把Go語言稱作為區(qū)塊鏈行業(yè)的開發(fā)語言。如果大家學(xué)習(xí)區(qū)塊鏈技術(shù)的話,就會發(fā)現(xiàn)現(xiàn)在有很多很多的區(qū)塊鏈的系統(tǒng)和應(yīng)用都是采用Go進(jìn)行開發(fā)的,比如ehtereum是目前知名度最大的公鏈,再比如fabric是目前最知名的聯(lián)盟鏈,兩者都有g(shù)o語言的版本,且go-ehtereum還是以太坊官方推薦的版本。

自1.0版發(fā)布以來,go語言引起了眾多開發(fā)者的關(guān)注,并得到了廣泛的應(yīng)用。go語言簡單、高效、并發(fā)的特點(diǎn)吸引了許多傳統(tǒng)的語言開發(fā)人員,其數(shù)量也在不斷增加。

使用 Go 語言開發(fā)的開源項(xiàng)目非常多。早期的 Go 語言開源項(xiàng)目只是通過 Go 語言與傳統(tǒng)項(xiàng)目進(jìn)行C語言庫綁定實(shí)現(xiàn),例如 Qt、Sqlite 等。

后期的很多項(xiàng)目都使用 Go 語言進(jìn)行重新原生實(shí)現(xiàn),這個過程相對于其他語言要簡單一些,這也促成了大量使用 Go 語言原生開發(fā)項(xiàng)目的出現(xiàn)。

GO語言(二十七):管理依賴項(xiàng)(下)-

當(dāng)您對外部模塊的存儲庫進(jìn)行了 fork (例如修復(fù)模塊代碼中的問題或添加功能)時,您可以讓 Go 工具將您的 fork 用于模塊的源代碼。這對于測試您自己的代碼的更改很有用。

為此,您可以使用go.mod 文件中的replace指令將外部模塊的原始模塊路徑替換為存儲庫中 fork 的路徑。這指示 Go 工具在編譯時使用替換路徑(fork 的位置),例如,同時允許您保留import 原始模塊路徑中的語句不變。

在以下 go.mod 文件示例中,當(dāng)前模塊需要外部模塊example.com/theirmodule。然后該replace指令將原始模塊路徑替換為example.com/myfork/theirmodule模塊自己的存儲庫的分支。

設(shè)置require/replace對時,使用 Go 工具命令確保文件描述的需求保持一致。使用go list命令獲取當(dāng)前模塊正在使用的版本。然后使用go mod edit命令將需要的模塊替換為fork:

注意: 當(dāng)您使用該replace指令時,Go 工具不會像添加依賴項(xiàng)中所述對外部模塊進(jìn)行身份驗(yàn)證。

您可以使用go get命令從其存儲庫中的特定提交為模塊添加未發(fā)布的代碼。

為此,您使用go get命令,用符號@指定您想要的代碼 。當(dāng)您使用go get時,該命令將向您的 go.mod 文件添加一個 需要外部模塊的require指令,使用基于有關(guān)提交的詳細(xì)信息的偽版本號。

以下示例提供了一些說明。這些基于源位于 git 存儲庫中的模塊。

當(dāng)您的代碼不再使用模塊中的任何包時,您可以停止將該模塊作為依賴項(xiàng)進(jìn)行跟蹤。

要停止跟蹤所有未使用的模塊,請運(yùn)行g(shù)o mod tidy 命令。此命令還可能添加在模塊中構(gòu)建包所需的缺失依賴項(xiàng)。

要刪除特定依賴項(xiàng),請使用go get,指定模塊的模塊路徑并附加 @none,如下例所示:

go get命令還將降級或刪除依賴于已刪除模塊的其他依賴項(xiàng)。

當(dāng)您使用 Go 工具處理模塊時,這些工具默認(rèn)從 proxy.golang.org(一個公共的 Google 運(yùn)行的模塊鏡像)或直接從模塊的存儲庫下載模塊。您可以指定 Go 工具應(yīng)該使用另一個代理服務(wù)器來下載和驗(yàn)證模塊。

如果您(或您的團(tuán)隊(duì))已經(jīng)設(shè)置或選擇了您想要使用的不同模塊代理服務(wù)器,您可能想要這樣做。例如,有些人設(shè)置了模塊代理服務(wù)器,以便更好地控制依賴項(xiàng)的使用方式。

要為 Go 工具指定另一個模塊代理服務(wù)器,請將GOPROXY 環(huán)境變量設(shè)置為一個或多個服務(wù)器的 URL。Go 工具將按照您指定的順序嘗試每個 URL。默認(rèn)情況下,GOPROXY首先指定一個公共的 Google 運(yùn)行模塊代理,然后從模塊的存儲庫直接下載(在其模塊路徑中指定):

您可以將變量設(shè)置為其他模塊代理服務(wù)器的 URL,用逗號或管道分隔 URL。

Go 模塊經(jīng)常在公共互聯(lián)網(wǎng)上不可用的版本控制服務(wù)器和模塊代理上開發(fā)和分發(fā)。您可以設(shè)置 GOPRIVATE環(huán)境變量。您可以設(shè)置GOPRIVATE環(huán)境變量來配置go命令以從私有源下載和構(gòu)建模塊。然后 go 命令可以從私有源下載和構(gòu)建模塊。

GOPRIVATE或環(huán)境變量可以設(shè)置為匹配模塊前綴的全局模式列表,這些GONOPROXY前綴是私有的,不應(yīng)從任何代理請求。例如:

標(biāo)題名稱:go語言的模式匹配 go語言比較
地址分享:http://muchs.cn/article8/hjcpop.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供動態(tài)網(wǎng)站、定制網(wǎng)站、云服務(wù)器網(wǎng)站策劃、網(wǎng)站導(dǎo)航、網(wǎng)頁設(shè)計公司

廣告

聲明:本網(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)

成都網(wǎng)站建設(shè)公司