欧美一区二区三区老妇人-欧美做爰猛烈大尺度电-99久久夜色精品国产亚洲a-亚洲福利视频一区二区

go語言反射作用 go語言反射的使用場景

講講go語言的結(jié)構(gòu)體

作為C語言家族的一員,go和c一樣也支持結(jié)構(gòu)體。可以類比于java的一個POJO。

成都創(chuàng)新互聯(lián)自2013年起,是專業(yè)互聯(lián)網(wǎng)技術(shù)服務(wù)公司,擁有項目成都網(wǎng)站建設(shè)、網(wǎng)站建設(shè)網(wǎng)站策劃,項目實施與項目整合能力。我們以讓每一個夢想脫穎而出為使命,1280元福貢做網(wǎng)站,已為上家服務(wù),為福貢各地企業(yè)和個人服務(wù),聯(lián)系電話:13518219792

在學(xué)習(xí)定義結(jié)構(gòu)體之前,先學(xué)習(xí)下定義一個新類型。

新類型 T1 是基于 Go 原生類型 int 定義的新自定義類型,而新類型 T2 則是 基于剛剛定義的類型 T1,定義的新類型。

這里要引入一個底層類型的概念。

如果一個新類型是基于某個 Go 原生類型定義的, 那么我們就叫 Go 原生類型為新類型的底層類型

在上面的例子中,int就是T1的底層類型。

但是T1不是T2的底層類型,只有原生類型才可以作為底層類型,所以T2的底層類型還是int

底層類型是很重要的,因為對兩個變量進行顯式的類型轉(zhuǎn)換,只有底層類型相同的變量間才能相互轉(zhuǎn)換。底層類型是判斷兩個類型本質(zhì)上是否相同的根本。

這種類型定義方式通常用在 項目的漸進式重構(gòu),還有對已有包的二次封裝方面

類型別名表示新類型和原類型完全等價,實際上就是同一種類型。只不過名字不同而已。

一般我們都是定義一個有名的結(jié)構(gòu)體。

字段名的大小寫決定了字段是否包外可用。只有大寫的字段可以被包外引用。

還有一個點提一下

如果換行來寫

Age: 66,后面這個都好不能省略

還有一個點,觀察e3的賦值

new返回的是一個指針。然后指針可以直接點號賦值。這說明go默認(rèn)進行了取值操作

e3.Age 等價于 (*e3).Age

如上定義了一個空的結(jié)構(gòu)體Empty。打印了元素e的內(nèi)存大小是0。

有什么用呢?

基于空結(jié)構(gòu)體類型內(nèi)存零開銷這樣的特性,我們在日常 Go 開發(fā)中會經(jīng)常使用空 結(jié)構(gòu)體類型元素,作為一種“事件”信息進行 Goroutine 之間的通信

這種以空結(jié)構(gòu)體為元素類建立的 channel,是目前能實現(xiàn)的、內(nèi)存占用最小的 Goroutine 間通信方式。

這種形式需要說的是幾個語法糖。

語法糖1:

對于結(jié)構(gòu)體字段,可以省略字段名,只寫結(jié)構(gòu)體名。默認(rèn)字段名就是結(jié)構(gòu)體名

這種方式稱為 嵌入字段

語法糖2:

如果是以嵌入字段形式寫的結(jié)構(gòu)體

可以省略嵌入的Reader字段,而直接訪問ReaderName

此時book是一個各個屬性全是對應(yīng)類型零值的一個實例。不是nil。這種情況在Go中稱為零值可用。不像java會導(dǎo)致npe

結(jié)構(gòu)體定義時可以在字段后面追加標(biāo)簽說明。

tag的格式為反單引號

tag的作用是可以使用[反射]來檢視字段的標(biāo)簽信息。

具體的作用還要看使用的場景。

比如這里的tag是為了幫助 encoding/json 標(biāo)準(zhǔn)包在解析對象時可以利用的規(guī)則。比如omitempty表示該字段沒有值就不打印出來。

go語言中的反射

import (

"fmt"

"reflect"

)

func reflecType(x interface{}){

v := reflect.TypeOf(x)

fmt.Println("type:%v\n", v)

fmt.Println("type name:%v , rtpe kind:%v \n", v.getName(), v.getType())

}

type Cat struct{}

//通過反射設(shè)置變量的值

func reflectSetValue1(x interface{}){

v := reflect.ValueOf(x)

if v.Kind() == reflect.Int64{

v.SetInt(200) //修改的是副本, reflect 包會引發(fā)panic

}

}

//通過反射設(shè)置變量的值

func reflectSetValue2(x interface{}){

v := reflect.ValueOf(x)

//反射中使用Elem()獲取指針對應(yīng)的值

if v.Elem().Kind() == reflect.Int64{

v.Elem().SetInt(200)

}

}

func main(){

var a float32 = 3.14

reflectType(a) //type name:float32 type kind:float32

var b int64 = 100

reflectType(b) // type name :int64 type kind :int64

var c = Cat{}

reflectType(c) // type name :Cat type kind :struct

reflectSetValue1(b)

fmt.Println(b) //依然為100

reflectSetValue2(b)

}

go語言是一種什么語言

Go語言是谷歌推出的一種全新的編程語言,可以在不損失應(yīng)用程序性能的情況下降低代碼的復(fù)雜性。谷歌首席軟件工程師羅布派克(Rob Pike)說:我們之所以開發(fā)Go,是因為過去10多年間軟件開發(fā)的難度令人沮喪。

Go是谷歌2009發(fā)布的第二款編程語言。2009年7月份,谷歌曾發(fā)布了Simple語言,它是用來開發(fā)Android應(yīng)用

Go Logo

的一種BASIC語言.

北京時間2010年1月10日,Go語言摘得了TIOBE公布的2009年年度大獎。該獎項授予在2009年市場份額增長最多的編程語言。

谷歌資深軟件工程師羅布·派克(Rob Pike)表示,“Go讓我體驗到了從未有過的開發(fā)效率。”派克表示,和今天的C++或C一樣,Go是一種系統(tǒng)語言。他解釋道,“使用它可以進行快速開發(fā),同時它還是一個真正的編譯語言,我們之所以現(xiàn)在將其開源,原因是我們認(rèn)為它已經(jīng)非常有用和強大。”

2007年,谷歌把Go作為一個20%項目開始研發(fā),即讓員工抽出本職工作之外時間的20%, 投入在該項目上。除了派克外,該項目的成員還有其他谷歌工程師也參與研發(fā)。

派克表示,編譯后Go代碼的運行速度與C語言非常接近,而且編譯速度非常快,就像在使用一個交互式語言。現(xiàn)有編程語言均未專門對多核處理器進行優(yōu)化。Go就是谷歌工程師為這類程序編寫的一種語言。它不是針對編程初學(xué)者設(shè)計的,但學(xué)習(xí)使用它也不是非常困難。Go支持面向?qū)ο螅揖哂姓嬲拈]包(closures)和反射 (reflection)等功能。

在學(xué)習(xí)曲線方面,派克認(rèn)為Go與Java類似,對于Java開發(fā)者來說,應(yīng)該能夠輕松學(xué)會 Go。之所以將Go作為一個開源項目發(fā)布,目的是讓開源社區(qū)有機會創(chuàng)建更好的工具來使用該語言,例如 Eclipse IDE中的插件。

在谷歌公開發(fā)布的所有網(wǎng)絡(luò)應(yīng)用中,均沒有使用Go,但是谷歌已經(jīng)使用該語言開發(fā)了幾個內(nèi)部項目。派克表示,Go是否會對谷歌即將推出的Chrome OS產(chǎn)生影響,還言之尚早,不過Go的確可以和Native Client配合使用。他表示“Go可以讓應(yīng)用完美的運行在瀏覽器內(nèi)。”例如,使用Go可以更高效的實現(xiàn)Wave,無論是在前端還是后臺。

Go 同時具有兩種編譯器,一種是建立在GCC基礎(chǔ)上的Gccgo,另外一種是分別針對64位x64和32位x86計算機的一套編譯器(6g和8g)。谷歌目前正在研發(fā)其對ARM芯片和Android設(shè)備的支持。派克表示,“Android手機存在的問題是,我們一直沒有一個數(shù)學(xué)協(xié)處理器。

golang reflect反射(一):interface接口的入門(大白話)

這是它的優(yōu)點,因為編譯器在編譯時不去確定你傳的到底是什么類型,你傳一個string,它能接收,你傳一個對象struct,它也能接收,它只有一個要求,實現(xiàn)我要求實現(xiàn)的方法!

既然interface是不限定類型,是通用類型,這是一種開放表現(xiàn),這種開放怎么實現(xiàn)的呢?方法就是不去檢驗?zāi)愕念愋停热徊粰z驗?zāi)且膊蝗ビ涗浤愕念愋停。。。∽⒁鈏nterface不記錄你的類型,所以不管你是string,struct,int,我都不管,我都不記錄,我只記錄你的地址,結(jié)果是編譯器在編譯時也不知道你是什么類型,你有什么字段!

但是現(xiàn)在有一個問題,編譯器也沒辦法確定一個interface以前是什么類型!(編譯時)這就是因果關(guān)系:為了達(dá)到通用,interface不做確定工作,結(jié)果就是interface也不知道以前的類型。

一個類型轉(zhuǎn)接口的過程,就是放棄自我類型的過程,變成了沒有類型。

這樣做有什么好處呢,很顯然是:通用,如果把一個函數(shù)的傳入?yún)?shù)設(shè)置為空接口(interface{}),那么任何類型當(dāng)做參數(shù)都能夠調(diào)用該接口,最好的例子就是:

它就是一個很標(biāo)準(zhǔn)的例子,println傳入?yún)?shù)可以是任何類型,都能打印出它的值。

當(dāng)然你可以說你記得,因為是你把它轉(zhuǎn)換成interface,你理所當(dāng)然的記得,可編譯器不知道啊,interface不包含類型,也就是說你沒有讓它去記錄,所以它不知道。

針對這個問題,go語言給了一個解決方案,斷言,當(dāng)將一個interface轉(zhuǎn)換成它原來類型的時候,在它后面指明它的原來類型,這樣編譯器就知道該按照什么類型去解析了。(其實說白了,這就是通過人的記憶,編譯器不知道是什么類型,你告訴編譯器就可以了)

斷言其實是先獲取interface的動態(tài)類型,然后與你指定的類型做判斷,如果一致,將它轉(zhuǎn)換成你指定的類型。如果不知道動態(tài)類型,可以看這篇文章:

從報錯可以看出, 不能直接轉(zhuǎn)換,需要對接口先進行斷言

通常情況下,一個變量在確定類型的情況下編譯器知道他有哪些功能(注意,這里是針對編譯時),比如一個int類型,編譯器在編譯時知道能對他加減int,不能加減float,如果你這么做我就給你報錯。一個struct包含哪些字段,不包含哪些字段,我定義一個user結(jié)構(gòu)體,里面只有name和age兩個字段,那么你只能取我這兩字段的值,你如果取height,我就給你報錯。

這些都是正常情況下的,但是對于一個接口呢,編譯器會變成瞎子!在編譯的時候它不知道你原來是什么類型,所以它也沒法確定你包含什么字段,同樣是之前那個user結(jié)構(gòu)體,當(dāng)把它轉(zhuǎn)換成接口以后,編譯器就對它的類型一無所知了,你獲取name字段,這有接口有沒有呢?編譯器不知道!你請求height字段,這個泛型有沒有呢?編譯器仍然不知道。所以你編譯時不能修改接口里的數(shù)據(jù),既然編譯時 不能修改,那就只能在運行時修改了。

這個時候就該反射登場了,它能夠在運行時修改接口的數(shù)據(jù),通過追根溯源,獲取接口底層的實際數(shù)據(jù)和類型,讓你能夠?qū)涌诘脑磾?shù)據(jù)進行操作。

換一種大白話的說法,反射就是刨根問底,獲取這個接口究竟是怎么產(chǎn)生的,因為哪怕一個類型轉(zhuǎn)變成接口時放棄了自己的類型,但是它的本質(zhì)不會變的,就像趙本山的小品里所說:小樣,別以為你脫掉馬甲我就不認(rèn)識你了!對,它的底層里仍然存儲了它的數(shù)據(jù)類型,只是藏的比較深,一般手段拿不到,但我們?nèi)匀荒軌蛲ㄟ^反射(這個包根問底的工具)來確定你究竟包含哪些字段和值,確定你究竟是蛇還是脫了馬甲的烏龜!

分享標(biāo)題:go語言反射作用 go語言反射的使用場景
瀏覽地址:http://chinadenli.net/article30/ddgsppo.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供營銷型網(wǎng)站建設(shè)云服務(wù)器定制開發(fā)全網(wǎng)營銷推廣網(wǎng)站收錄做網(wǎng)站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

成都定制網(wǎng)站網(wǎng)頁設(shè)計