
這是它的優(yōu)點(diǎn),因?yàn)榫幾g器在編譯時(shí)不去確定你傳的到底是什么類(lèi)型,你傳一個(gè)string,它能接收,你傳一個(gè)對(duì)象struct,它也能接收,它只有一個(gè)要求,實(shí)現(xiàn)我要求實(shí)現(xiàn)的方法!

公司專(zhuān)注于為企業(yè)提供成都網(wǎng)站設(shè)計(jì)、網(wǎng)站制作、外貿(mào)營(yíng)銷(xiāo)網(wǎng)站建設(shè)、微信公眾號(hào)開(kāi)發(fā)、商城建設(shè),微信小程序,軟件定制網(wǎng)站建設(shè)等一站式互聯(lián)網(wǎng)企業(yè)服務(wù)。憑借多年豐富的經(jīng)驗(yàn),我們會(huì)仔細(xì)了解各客戶(hù)的需求而做出多方面的分析、設(shè)計(jì)、整合,為客戶(hù)設(shè)計(jì)出具風(fēng)格及創(chuàng)意性的商業(yè)解決方案,成都創(chuàng)新互聯(lián)公司更提供一系列網(wǎng)站制作和網(wǎng)站推廣的服務(wù)。
既然interface是不限定類(lèi)型,是通用類(lèi)型,這是一種開(kāi)放表現(xiàn),這種開(kāi)放怎么實(shí)現(xiàn)的呢?方法就是不去檢驗(yàn)?zāi)愕念?lèi)型,既然不檢驗(yàn)?zāi)且膊蝗ビ涗浤愕念?lèi)型?。。?!注意interface不記錄你的類(lèi)型,所以不管你是string,struct,int,我都不管,我都不記錄,我只記錄你的地址,結(jié)果是編譯器在編譯時(shí)也不知道你是什么類(lèi)型,你有什么字段!
但是現(xiàn)在有一個(gè)問(wèn)題,編譯器也沒(méi)辦法確定一個(gè)interface以前是什么類(lèi)型?。ň幾g時(shí))這就是因果關(guān)系:為了達(dá)到通用,interface不做確定工作,結(jié)果就是interface也不知道以前的類(lèi)型。
一個(gè)類(lèi)型轉(zhuǎn)接口的過(guò)程,就是放棄自我類(lèi)型的過(guò)程,變成了沒(méi)有類(lèi)型。
這樣做有什么好處呢,很顯然是:通用,如果把一個(gè)函數(shù)的傳入?yún)?shù)設(shè)置為空接口(interface{}),那么任何類(lèi)型當(dāng)做參數(shù)都能夠調(diào)用該接口,最好的例子就是:
它就是一個(gè)很標(biāo)準(zhǔn)的例子,println傳入?yún)?shù)可以是任何類(lèi)型,都能打印出它的值。
當(dāng)然你可以說(shuō)你記得,因?yàn)槭悄惆阉D(zhuǎn)換成interface,你理所當(dāng)然的記得,可編譯器不知道啊,interface不包含類(lèi)型,也就是說(shuō)你沒(méi)有讓它去記錄,所以它不知道。
針對(duì)這個(gè)問(wèn)題,go語(yǔ)言給了一個(gè)解決方案,斷言,當(dāng)將一個(gè)interface轉(zhuǎn)換成它原來(lái)類(lèi)型的時(shí)候,在它后面指明它的原來(lái)類(lèi)型,這樣編譯器就知道該按照什么類(lèi)型去解析了。(其實(shí)說(shuō)白了,這就是通過(guò)人的記憶,編譯器不知道是什么類(lèi)型,你告訴編譯器就可以了)
斷言其實(shí)是先獲取interface的動(dòng)態(tài)類(lèi)型,然后與你指定的類(lèi)型做判斷,如果一致,將它轉(zhuǎn)換成你指定的類(lèi)型。如果不知道動(dòng)態(tài)類(lèi)型,可以看這篇文章:
從報(bào)錯(cuò)可以看出, 不能直接轉(zhuǎn)換,需要對(duì)接口先進(jìn)行斷言
通常情況下,一個(gè)變量在確定類(lèi)型的情況下編譯器知道他有哪些功能(注意,這里是針對(duì)編譯時(shí)),比如一個(gè)int類(lèi)型,編譯器在編譯時(shí)知道能對(duì)他加減int,不能加減float,如果你這么做我就給你報(bào)錯(cuò)。一個(gè)struct包含哪些字段,不包含哪些字段,我定義一個(gè)user結(jié)構(gòu)體,里面只有name和age兩個(gè)字段,那么你只能取我這兩字段的值,你如果取height,我就給你報(bào)錯(cuò)。
這些都是正常情況下的,但是對(duì)于一個(gè)接口呢,編譯器會(huì)變成瞎子!在編譯的時(shí)候它不知道你原來(lái)是什么類(lèi)型,所以它也沒(méi)法確定你包含什么字段,同樣是之前那個(gè)user結(jié)構(gòu)體,當(dāng)把它轉(zhuǎn)換成接口以后,編譯器就對(duì)它的類(lèi)型一無(wú)所知了,你獲取name字段,這有接口有沒(méi)有呢?編譯器不知道!你請(qǐng)求height字段,這個(gè)泛型有沒(méi)有呢?編譯器仍然不知道。所以你編譯時(shí)不能修改接口里的數(shù)據(jù),既然編譯時(shí) 不能修改,那就只能在運(yùn)行時(shí)修改了。
這個(gè)時(shí)候就該反射登場(chǎng)了,它能夠在運(yùn)行時(shí)修改接口的數(shù)據(jù),通過(guò)追根溯源,獲取接口底層的實(shí)際數(shù)據(jù)和類(lèi)型,讓你能夠?qū)涌诘脑磾?shù)據(jù)進(jìn)行操作。
換一種大白話(huà)的說(shuō)法,反射就是刨根問(wèn)底,獲取這個(gè)接口究竟是怎么產(chǎn)生的,因?yàn)槟呐乱粋€(gè)類(lèi)型轉(zhuǎn)變成接口時(shí)放棄了自己的類(lèi)型,但是它的本質(zhì)不會(huì)變的,就像趙本山的小品里所說(shuō):小樣,別以為你脫掉馬甲我就不認(rèn)識(shí)你了!對(duì),它的底層里仍然存儲(chǔ)了它的數(shù)據(jù)類(lèi)型,只是藏的比較深,一般手段拿不到,但我們?nèi)匀荒軌蛲ㄟ^(guò)反射(這個(gè)包根問(wèn)底的工具)來(lái)確定你究竟包含哪些字段和值,確定你究竟是蛇還是脫了馬甲的烏龜!
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{}
//通過(guò)反射設(shè)置變量的值
func reflectSetValue1(x interface{}){
v := reflect.ValueOf(x)
if v.Kind() == reflect.Int64{
v.SetInt(200) //修改的是副本, reflect 包會(huì)引發(fā)panic
}
}
//通過(guò)反射設(shè)置變量的值
func reflectSetValue2(x interface{}){
v := reflect.ValueOf(x)
//反射中使用Elem()獲取指針對(duì)應(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語(yǔ)言是谷歌推出的一種全新的編程語(yǔ)言,可以在不損失應(yīng)用程序性能的情況下降低代碼的復(fù)雜性。谷歌首席軟件工程師羅布派克(Rob Pike)說(shuō):我們之所以開(kāi)發(fā)Go,是因?yàn)檫^(guò)去10多年間軟件開(kāi)發(fā)的難度令人沮喪。
Go是谷歌2009發(fā)布的第二款編程語(yǔ)言。2009年7月份,谷歌曾發(fā)布了Simple語(yǔ)言,它是用來(lái)開(kāi)發(fā)Android應(yīng)用
Go Logo
的一種BASIC語(yǔ)言.
北京時(shí)間2010年1月10日,Go語(yǔ)言摘得了TIOBE公布的2009年年度大獎(jiǎng)。該獎(jiǎng)項(xiàng)授予在2009年市場(chǎng)份額增長(zhǎng)最多的編程語(yǔ)言。
谷歌資深軟件工程師羅布·派克(Rob Pike)表示,“Go讓我體驗(yàn)到了從未有過(guò)的開(kāi)發(fā)效率。”派克表示,和今天的C++或C一樣,Go是一種系統(tǒng)語(yǔ)言。他解釋道,“使用它可以進(jìn)行快速開(kāi)發(fā),同時(shí)它還是一個(gè)真正的編譯語(yǔ)言,我們之所以現(xiàn)在將其開(kāi)源,原因是我們認(rèn)為它已經(jīng)非常有用和強(qiáng)大?!?/p>
2007年,谷歌把Go作為一個(gè)20%項(xiàng)目開(kāi)始研發(fā),即讓員工抽出本職工作之外時(shí)間的20%, 投入在該項(xiàng)目上。除了派克外,該項(xiàng)目的成員還有其他谷歌工程師也參與研發(fā)。
派克表示,編譯后Go代碼的運(yùn)行速度與C語(yǔ)言非常接近,而且編譯速度非??欤拖裨谑褂靡粋€(gè)交互式語(yǔ)言?,F(xiàn)有編程語(yǔ)言均未專(zhuān)門(mén)對(duì)多核處理器進(jìn)行優(yōu)化。Go就是谷歌工程師為這類(lèi)程序編寫(xiě)的一種語(yǔ)言。它不是針對(duì)編程初學(xué)者設(shè)計(jì)的,但學(xué)習(xí)使用它也不是非常困難。Go支持面向?qū)ο?,而且具有真正的閉包(closures)和反射 (reflection)等功能。
在學(xué)習(xí)曲線(xiàn)方面,派克認(rèn)為Go與Java類(lèi)似,對(duì)于Java開(kāi)發(fā)者來(lái)說(shuō),應(yīng)該能夠輕松學(xué)會(huì) Go。之所以將Go作為一個(gè)開(kāi)源項(xiàng)目發(fā)布,目的是讓開(kāi)源社區(qū)有機(jī)會(huì)創(chuàng)建更好的工具來(lái)使用該語(yǔ)言,例如 Eclipse IDE中的插件。
在谷歌公開(kāi)發(fā)布的所有網(wǎng)絡(luò)應(yīng)用中,均沒(méi)有使用Go,但是谷歌已經(jīng)使用該語(yǔ)言開(kāi)發(fā)了幾個(gè)內(nèi)部項(xiàng)目。派克表示,Go是否會(huì)對(duì)谷歌即將推出的Chrome OS產(chǎn)生影響,還言之尚早,不過(guò)Go的確可以和Native Client配合使用。他表示“Go可以讓?xiě)?yīng)用完美的運(yùn)行在瀏覽器內(nèi)?!崩纾褂肎o可以更高效的實(shí)現(xiàn)Wave,無(wú)論是在前端還是后臺(tái)。
Go 同時(shí)具有兩種編譯器,一種是建立在GCC基礎(chǔ)上的Gccgo,另外一種是分別針對(duì)64位x64和32位x86計(jì)算機(jī)的一套編譯器(6g和8g)。谷歌目前正在研發(fā)其對(duì)ARM芯片和Android設(shè)備的支持。派克表示,“Android手機(jī)存在的問(wèn)題是,我們一直沒(méi)有一個(gè)數(shù)學(xué)協(xié)處理器。