這是它的優點,因為編譯器在編譯時不去確定你傳的到底是什么類型,你傳一個string,它能接收,你傳一個對象struct,它也能接收,它只有一個要求,實現我要求實現的方法!
創新互聯專業提供成都主機托管四川主機托管成都服務器托管四川服務器托管,支持按月付款!我們的承諾:貴族品質、平民價格,機房位于中國電信/網通/移動機房,成都二樞服務器租用托管服務有保障!
既然interface是不限定類型,是通用類型,這是一種開放表現,這種開放怎么實現的呢?方法就是不去檢驗你的類型,既然不檢驗那也不去記錄你的類型!!!!注意interface不記錄你的類型,所以不管你是string,struct,int,我都不管,我都不記錄,我只記錄你的地址,結果是編譯器在編譯時也不知道你是什么類型,你有什么字段!
但是現在有一個問題,編譯器也沒辦法確定一個interface以前是什么類型!(編譯時)這就是因果關系:為了達到通用,interface不做確定工作,結果就是interface也不知道以前的類型。
一個類型轉接口的過程,就是放棄自我類型的過程,變成了沒有類型。
這樣做有什么好處呢,很顯然是:通用,如果把一個函數的傳入參數設置為空接口(interface{}),那么任何類型當做參數都能夠調用該接口,最好的例子就是:
它就是一個很標準的例子,println傳入參數可以是任何類型,都能打印出它的值。
當然你可以說你記得,因為是你把它轉換成interface,你理所當然的記得,可編譯器不知道啊,interface不包含類型,也就是說你沒有讓它去記錄,所以它不知道。
針對這個問題,go語言給了一個解決方案,斷言,當將一個interface轉換成它原來類型的時候,在它后面指明它的原來類型,這樣編譯器就知道該按照什么類型去解析了。(其實說白了,這就是通過人的記憶,編譯器不知道是什么類型,你告訴編譯器就可以了)
斷言其實是先獲取interface的動態類型,然后與你指定的類型做判斷,如果一致,將它轉換成你指定的類型。如果不知道動態類型,可以看這篇文章:
從報錯可以看出, 不能直接轉換,需要對接口先進行斷言
通常情況下,一個變量在確定類型的情況下編譯器知道他有哪些功能(注意,這里是針對編譯時),比如一個int類型,編譯器在編譯時知道能對他加減int,不能加減float,如果你這么做我就給你報錯。一個struct包含哪些字段,不包含哪些字段,我定義一個user結構體,里面只有name和age兩個字段,那么你只能取我這兩字段的值,你如果取height,我就給你報錯。
這些都是正常情況下的,但是對于一個接口呢,編譯器會變成瞎子!在編譯的時候它不知道你原來是什么類型,所以它也沒法確定你包含什么字段,同樣是之前那個user結構體,當把它轉換成接口以后,編譯器就對它的類型一無所知了,你獲取name字段,這有接口有沒有呢?編譯器不知道!你請求height字段,這個泛型有沒有呢?編譯器仍然不知道。所以你編譯時不能修改接口里的數據,既然編譯時 不能修改,那就只能在運行時修改了。
這個時候就該反射登場了,它能夠在運行時修改接口的數據,通過追根溯源,獲取接口底層的實際數據和類型,讓你能夠對接口的源數據進行操作。
換一種大白話的說法,反射就是刨根問底,獲取這個接口究竟是怎么產生的,因為哪怕一個類型轉變成接口時放棄了自己的類型,但是它的本質不會變的,就像趙本山的小品里所說:小樣,別以為你脫掉馬甲我就不認識你了!對,它的底層里仍然存儲了它的數據類型,只是藏的比較深,一般手段拿不到,但我們仍然能夠通過反射(這個包根問底的工具)來確定你究竟包含哪些字段和值,確定你究竟是蛇還是脫了馬甲的烏龜!
要判斷數據類型,可以用Go的空接口: 建一個函數t 設置參數i 的類型為空接口,空接口可以接受任何數據類型 func t(i interface{}) { //函數t 有一個參數i switch i.(type) { //多選語句switch case string: //是字符時做的事情 case int: //是整...
接口像是一個公司里面的領導,他會定義一些通用規范,只設計規范,而不實現規范。
go語言的接口,是一種新的類型定義,它把所有的具有共性的方法定義在一起,任何其他類型只要實現了這些方法就是實現了這個接口。
語法格式和方法非常類似。
在接口定義中定義,若干個空方法。這些方法都具有通用性。
下面我定義一個USB接口,有讀read和寫write兩個方法,再定義一個電腦Computer和一個手機Mobile來實現這個接口。
USB接口
Computer結構體
Mobile結構體
Computer實現USB接口方法
Mobile實現USB接口方法
測試
運行結果
下面我們定義一個OpenClose接口,里面有兩個方法open和close,定義個Door結構體,實現其中一個方法。
import "workname/packetfolder"
導入多個包
方法調用 包名.函數//不是函數或結構體所處文件或文件夾名
packagename.Func()
前面加個點表示省略調用,那么調用該模塊里面的函數,可以不用寫模塊名稱了:
當導入一個包時,該包下的文件里所有init()函數都會被執行,然而,有些時候我們并不需要把整個包都導入進來,僅僅是是希望它執行init()函數而已。下劃線的作用僅僅是為了調用init()函數,所以無法通過包名來調用包中的其他函數
import _ package
變量聲明必須要使用否則會報錯。
全局變量運行聲明但不使用。
func 函數名 (參數1,參數2,...) (返回值a 類型a, 返回值b 類型b,...)
func 函數名 (參數1,參數2,...) (返回值類型1, 返回值類型2,...)
func (this *結構體名) 函數名(參數 string) (返回值類型1, 返回值類型2){}
使用大小來區分函數可見性
大寫是public類型
小寫是private類型
func prifunc int{}
func pubfunc int{}
聲明靜態變量
const value int
定義變量
var value int
聲明一般類型、接口和結構體
聲明函數
func function () int{}
go里面所有的空值對應如下
通道類型
內建函數 new 用來分配內存,它的第一個參數是一個類型,不是一個值,它的返回值是一個指向新分配類型零值的指針
func new(Type) *Type
[這位博主有非常詳細的分析]
Go 語言支持并發,我們只需要通過 go 關鍵字來開啟 goroutine 即可。
goroutine 是輕量級線程,goroutine 的調度是由 Golang 運行時進行管理的。
同一個程序中的所有 goroutine 共享同一個地址空間。
語法格式如下:
通道(channel)是用來傳遞數據的一個數據結構。
通道的聲明
通道可用于兩個 goroutine 之間通過傳遞一個指定類型的值來同步運行和通訊。操作符 - 用于指定通道的方向,發送或接收。如果未指定方向,則為雙向通道。
[這里有比較詳細的用例]
go里面的空接口可以指代任何類型(無論是變量還是函數)
聲明空接口
go里面的的強制類型轉換語法為:
int(data)
如果是接口類型的強制轉成其他類型的語法為:
go里面的強制轉換是將值復制過去,所以在數據量的時候有比較高的運行代價
你說的應該是這樣:
var?User?interface{}
這個是空接口,代表任意類型的意思,因為所有類型都滿足空接口
網站欄目:go語言空接口的使用 go 函數實現接口
分享網址:http://m.kartarina.com/article20/dodsgco.html
成都網站建設公司_創新互聯,為您提供用戶體驗、企業建站、定制開發、建站公司、企業網站制作、網站制作
聲明:本網站發布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創新互聯