golang插口,golang介面深入理解

本文目錄一覽:

golang傳遞介面類型參數時,什麼時候用指針

因為 interface 類型本質上就是 2 個 uintptr(一個表示 type 一個表示 value)。當你連 2 個 uintptr 都不想拷貝的時候,你就會用到指向 interface 的指針了。

當然,你用一個新的 uintptr 指向另一個 2 個 uintptr 長度的對象,也沒省多少事兒

golang如何去封裝外部介面

1.為什麼golang的開發效率高?golang是一編譯型的強類型語言,它在開發上的高效率主要來自於後發優勢,不用考慮舊有噁心的歷史,又有一個較高的工程視角。良好的避免了程序員因為「{需不需要獨佔一行」這種革命問題打架,也解決了一部分趁編譯時間找產品妹妹搭訕的階級敵人。它有自己的包管理機制,工具鏈成熟,從開發、調試到發布都很簡單方便;有反向介面、defer、coroutine等大量的syntacticsugar;編譯速度快,因為是強類型語言又有gc,只要通過編譯,非業務毛病就很少了;它在語法級別上支持了goroutine,這是大家說到最多的內容,這裡重點提一下。首先,coroutine並不稀罕,語言並不能超越硬體、操作系統實現神乎其神的功能。golang可以做到事情,其他語言也可以做到,譬如c++,在boost庫裡面自己就有的coroutine實現(當然用起來跟其他boost庫一樣噁心)。golang做的事情,是把這一套東西的使用過程簡化了,並且提供了一套channel的通信模式,使得程序員可以忽略諸如死鎖等問題。goroutine的目的是描述並發編程模型。並發與並行不同,它並不需要多核的硬體支持,它不是一種物理運行狀態,而是一種程序邏輯流程。它的主要目的不是利用多核提高運行效率,而是提供一種更容易理解、不容易出錯的語言來描述問題。實際上golang默認就是運行在單OS進程上面的,通過指定環境變數GOMAXPROCS才能轉身跑在多OS進程上面。有人提到了網易的pomelo,開源本來是一件很不錯的事情,但是基於自己對callbackhell的偏見,我一直持有這種態度:敢用nodejs寫大規模遊戲伺服器的人,都是真正的勇士:)。2、Erlang與Golang的coroutine有啥區別,coroutine是啥?coroutine本質上是語言開發者自己實現的、處於userspace內的線程,無論是erlang、還是golang都是這樣。需要解決沒有時鐘中斷;碰著阻塞式i\o,整個進程都會被操作系統主動掛起;需要自己擁有調度控制能力(放在並行環境下面還是挺麻煩的一件事)等等問題。那為啥要廢老大的勁自己做一套線程放userspace裡面呢?並發是伺服器語言必須要解決的問題;systemspace的進程還有線程調度都太慢了、佔用的空間也太大了。把線程放到userspace的可以避免了陷入systemcall進行上下文切換以及高速緩衝更新,線程本身以及切換等操作可以做得非常的輕量。這也就是golang這類語言反覆提及的超高並發能力,分分鐘給你開上幾千個線程不費力。不同的是,golang的並發調度在i/o等易發阻塞的時候才會發生,一般是內封在庫函數內;erlang則更誇張,對每個coroutine維持一個計數器,常用語句都會導致這個計數器進行reduction,一旦到點,立即切換調度函數。中斷介入程度的不同,導致erlang看上去擁有了preemptivescheduling的能力,而golang則是cooperativeshceduling的。golang一旦寫出純計算死循環,進程內所有會話必死無疑;要有大計算量少i\o的函數還得自己主動叫runtime.Sched()來進行調度切換。3、golang的運行效率怎麼樣?我是相當反感所謂的ping\pong式benchmark,運行效率需要放到具體的工作環境下面考慮。首先,它再快也是快不過c的,畢竟底下做了那麼多工作,又有調度,又有gc什麼的。那為什麼在那些benchmark裡面,golang、nodejs、erlang的響應效率看上去那麼優秀呢,響應快,並發強?並發能力強的原因上面已經提到了,響應快是因為大量非阻塞式i\o操作出現的原因。這一點c也可以做到,並且能力更強,但是得多寫不少優質代碼。然後,針對遊戲伺服器這種高實時性的運行環境,GC所造成的跳幀問題確實比較麻煩,前面的大神@達達有比較詳細的論述和緩解方案,就不累述了。隨著golang的持續開發,相信應該會有非常大的改進。一是屏蔽內存操作是現代語言的大勢所趨,它肯定是需要被實現的;二是GC演算法已經相當的成熟,效率勉勉強強過得去;三是可以通過incremental的操作來均攤cpu消耗。用這一點點效率損失換取一個更高的生產能力是不是值得呢?我覺得是值得的,硬體已經很便宜了,人生苦短,讓自己的生活更輕鬆一點吧:)。4、基於以上的論述,我認為採用go進行小範圍的MMORPG開發是可行的。

『No8: Go 介面』

大家好,我是謝偉,是一名程序員。

下面的學習是一個系列,力求從初學者的角度學會go 語言,達到中級程序員水平。

這一系列是我的輸出總結,同時我還推出了視頻版。正在製作過程。

為寫出這些文章,我閱讀了網上諸多熱門的教程和紙質書籍。內容的實質都是那些,要區分出差異的話,只能表現在具體實例層面。所以,實例我會選取自己在工作中的項目實例抽取出來。希望對大家有所幫助。

我們已經研究了:

本節的主題是:介面

介面是 golang 中最值得強調的特性。它讓面向對象,內容組織實現非常的方便。

介面在 go 語言中是一系列方法的集合,原則上方法可以有很多個,但建議4個左右。

上文中定義了一個 httpClient 的介面,指定了這個介面可以干這些活: Get、Post、Put、Delete

上文中指定了 httpClient 介面,指定了這個介面需要乾的活是: Get、Post、Put、Delete , 具體的實現需要靠其他結構體來實現。

一個結構體實現了介面要求的所有的方法(方法的參數和返回值一致),那麼就說這個結構體實現了這個介面

上文中的使用: httpClient 屏蔽了 httpImpl 的內部細節,而依然可以使用 Get 方法,去完成任務。

當然介面可以被諸多結構體實現,只需存在介面定義的幾種方法即可。

介面和結構體的定義很相似,也可以完成嵌入介面的功能,嵌入的匿名的介面,可以自動的具備被嵌入的介面的方法。

結構體實現 String 方法即可實現結構化輸出結構體。

實現Error 方法即可自定義錯誤類型。

這幾個讀寫介面在好些庫中實現了,後續我們再討論。

Any 類型

空介面在 go 里,可以當成任意類型,意味著,比如你的函數或者方法不知道傳入的參數的類型,可以直接定義為 interface{}

類型斷言

類型斷言的使用場景是:介面類型的變數可以包含任何類型的值。如何判斷變數的真實類型?

比如解析一個不知道欄位類型的 json, 常常需要使用到類型斷言。

可以使用:

ok…idiom

varInterface.(T), varInterface 必須是介面、T 則是具體的實現介面的結構體

switch ..case…

.(type) 只在 switch 語句里才能使用。

以上就是介面的全部內容,介面是go 中最特別的特性。藉助 介面, go 實現面向對象中的繼承和多態。

介面是方法的集合,只定義具體要幹什麼,而怎麼干,則由其他的結構體的方法實現。這樣不同的結構體的方法的具體處理不同,實現的介面的功能就不一樣。

儘管如此,介面並不意味著可以隨意濫用。我們最好是根據面向對象的客觀實體,抽象出介面和方法。

本節完,再會。

java怎麼調用golang的介面

1 介面的定義與理解

介面是一個自定義類型,它是一組方法的集合。從定義上來看,介面有兩個特點。第一,介面本質是一種自定義類型,因此不要將golang中的介面簡單理解為C++/Java中的介面,後者僅用於聲明方法簽名。第二,介面是一種特殊的自定義類型,其中沒有數據成員,只有方法(也可以為空)。

介面是完全抽象的,因此不能將其實例化。然而,可以創建一個其類型為介面的變數,它可以被賦值為任何滿足該介面類型的實際類型的值。介面的重要特性是:

(1)只要某個類型實現了介面要的方法,那麼我們就說該類型實現了此介面。該類型的值可以賦給該介面的值;

(2)作為1的推論,任何類型的值都可以賦值給空介面interface{}

注意:這只是golang中介面的特性,為非所有類型的特性(介面是一種特殊的類型)。

介面的特性是golang支持鴨子類型的基礎,即「如果它走起來像鴨子,叫起來像鴨子(實現了介面要的方法),它就是一隻鴨子(可以被賦值給介面的值)」。憑藉介面機制和鴨子類型,golang提供了一種有利於類、繼承、模板之外的更加靈活強大的選擇。

2 例子

type Exchanger interface {

exchange()

}

type StringPair struct {

first, second string

}

type Point[2]int

func (sp *StringPair) exchange() {

sp.first, sp.second = sp.second, sp.first

}

func (p *Point) exchange() {

p[0], p[1] = p[1], p[0]

}

func exchangeThese(exchangers …Exchanger) {

for _, exchanger := range exchangers {

exchanger.exchange()

}

}

func main() {

pair1 := StringPair{“abc”,”def”}

pair2 := StringPair{“ghi”,”jkl”}

point := Point{5, 7}

fmt.Println(pair1, pair2, point)

pair1.exchange()

pair2.exchange()

point.exchange()

fmt.Println(pair1, pair2, point)

// exchangeThese(pair1, pair2) //wrong

exchangeThese(pair1, pair2)

fmt.Println(pair1, pair2)

}

運行結果

在本例中,自定義類型StringPair和Point指針實現了介面Exchanger所需的方法,因此該類型的值可以被賦值給介面的值。

另外,特別注意一點。如果使用exchangeThese(pair1,

pair2)會導致編譯錯誤(如下圖),正確寫法應當是exchangeThese(pair1,

pair2)。這是由於真正滿足介面Exchanger的類型是StringPair指針,而非StringPair。

在golang中,值接收者和指針接收者的方法集是不同的。只是golang會智能地解引用和取引用,使得二者的方法集看上去是一樣的。但是,在調用exchangeThese時,就凸顯出二者的不同了。

go增刪改查要用介面定義嘛

要。

golang本身沒有提供連接mysql的驅動,但是定義了標準介面供第三方開發驅動。這裡連接mysql可以使用第三方庫。

關於反射

在計算機科學領域,反射是指一類應用,它們能夠自描述和自控制。也就是說,這類應用通過採用某種機制來實現對自己行為的描述(self-representation)和監測(examination),並能根據自身行為的狀態和結果,調整或修改應用所描述行為的狀態和相關的語義。

每種語言的反射模型都不同,並且有些語言根本不支持反射。Golang語言實現了反射,反射機制就是在運行時動態的調用對象的方法和屬性,官方自帶的reflect包就是反射相關的,只要包含這個包就可以使用。

多插一句,Golang的gRPC也是通過反射實現的。

在講反射之前,先來看看Golang關於類型設計的一些原則

接下來要講的反射,就是建立在類型之上的,Golang的指定類型的變數的類型是靜態的(也就是指定int、string這些的變數,它的type是static type),在創建變數的時候就已經確定,反射主要與Golang的interface類型相關(它的type是concrete type),只有interface類型才有反射一說。

在Golang的實現中,每個interface變數都有一個對應pair,pair中記錄了實際變數的值和類型:

value是實際變數值,type是實際變數的類型。一個interface{}類型的變數包含了2個指針,一個指針指向值的類型【對應concrete type】,另外一個指針指向實際的值【對應value】。

例如,創建類型為*os.File的變數,然後將其賦給一個介面變數r:

介面變數r的pair中將記錄如下信息:(tty, *os.File),這個pair在介面變數的連續賦值過程中是不變的,將介面變數r賦給另一個介面變數w:

介面變數w的pair與r的pair相同,都是:(tty, *os.File),即使w是空介面類型,pair也是不變的。

interface及其pair的存在,是Golang中實現反射的前提,理解了pair,就更容易理解反射。反射就是用來檢測存儲在介面變數內部(值value;類型concrete type) pair對的一種機制。

既然反射就是用來檢測存儲在介面變數內部(值value;類型concrete type) pair對的一種機制。那麼在Golang的reflect反射包中有什麼樣的方式可以讓我們直接獲取到變數內部的信息呢? 它提供了兩種類型(或者說兩個方法)讓我們可以很容易的訪問介面變數內容,分別是reflect.ValueOf() 和 reflect.TypeOf(),看看官方的解釋

reflect.TypeOf()是獲取pair中的type,reflect.ValueOf()獲取pair中的value,示例如下:

當執行reflect.ValueOf(interface)之後,就得到了一個類型為」relfect.Value」變數,可以通過它本身的Interface()方法獲得介面變數的真實內容,然後可以通過類型判斷進行轉換,轉換為原有真實類型。不過,我們可能是已知原有類型,也有可能是未知原有類型,因此,下面分兩種情況進行說明。

已知類型後轉換為其對應的類型的做法如下,直接通過Interface方法然後強制轉換,如下:

示例如下:

很多情況下,我們可能並不知道其具體類型,那麼這個時候,該如何做呢?需要我們進行遍歷探測其Filed來得知,示例如下:

通過運行結果可以得知獲取未知類型的interface的具體變數及其類型的步驟為:

通過運行結果可以得知獲取未知類型的interface的所屬方法(函數)的步驟為:

reflect.Value是通過reflect.ValueOf(X)獲得的,只有當X是指針的時候,才可以通過reflec.Value修改實際變數X的值,即:要修改反射類型的對象就一定要保證其值是「addressable」的。

示例如下:

這算是一個高級用法了,前面我們只說到對類型、變數的幾種反射的用法,包括如何獲取其值、其類型、如果重新設置新值。但是在工程應用中,另外一個常用並且屬於高級的用法,就是通過reflect來進行方法【函數】的調用。比如我們要做框架工程的時候,需要可以隨意擴展方法,或者說用戶可以自定義方法,那麼我們通過什麼手段來擴展讓用戶能夠自定義呢?關鍵點在於用戶的自定義方法是未可知的,因此我們可以通過reflect來搞定

示例如下:

Golang的反射很慢,這個和它的API設計有關。在 java 裡面,我們一般使用反射都是這樣來弄的。

這個取得的反射對象類型是 java.lang.reflect.Field。它是可以復用的。只要傳入不同的obj,就可以取得這個obj上對應的 field。

但是Golang的反射不是這樣設計的:

這裡取出來的 field 對象是 reflect.StructField 類型,但是它沒有辦法用來取得對應對象上的值。如果要取值,得用另外一套對object,而不是type的反射

這裡取出來的 fieldValue 類型是 reflect.Value,它是一個具體的值,而不是一個可復用的反射對象了,每次反射都需要malloc這個reflect.Value結構體,並且還涉及到GC。

Golang reflect慢主要有兩個原因

上述詳細說明了Golang的反射reflect的各種功能和用法,都附帶有相應的示例,相信能夠在工程應用中進行相應實踐,總結一下就是:

原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/153879.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
小藍的頭像小藍
上一篇 2024-11-15 03:23
下一篇 2024-11-15 03:23

相關推薦

  • 使用Golang調用Python

    在現代軟體開發中,多種編程語言的協作是相當普遍的。其中一種使用場景是Golang調用Python,這使得在使用Python庫的同時,可以利用Golang的高性能和強大並發能力。這篇…

    編程 2025-04-29
  • Java 監控介面返回信息報錯信息怎麼處理

    本文將從多個方面對 Java 監控介面返回信息報錯信息的處理方法進行詳細的闡述,其中包括如何捕獲異常、如何使用日誌輸出錯誤信息、以及如何通過異常處理機制解決報錯問題等等。以下是詳細…

    編程 2025-04-29
  • 使用Golang創建黑色背景圖片的方法

    本文將從多個方面介紹使用Golang創建黑色背景圖片的方法。 一、安裝必要的代碼庫和工具 在開始創建黑色背景圖片之前,我們需要先安裝必要的代碼庫和工具: go get -u git…

    編程 2025-04-29
  • Python介面自動化測試

    本文將從如下多個方面對Python編寫介面自動化進行詳細闡述,包括基本介紹、常用工具、測試框架、常見問題及解決方法 一、基本介紹 介面自動化測試是軟體測試中的一種自動化測試方式。通…

    編程 2025-04-27
  • Jadoor門鎖開發介面接入指南

    本文將從多個方面詳細介紹如何將門鎖接入Jadoor平台的開發介面,方便開發者們快速實現門鎖遠程控制、開鎖記錄查看等功能。 一、Jadoor門鎖開發介面簡介 Jadoor是一款用於密…

    編程 2025-04-27
  • 後端介面設計開發經驗分享

    在受到前端某些限制或特殊需求時,後端介面的設計和開發顯得尤為重要。下面從以下幾個方面進行講述。 一、命名規範 合理的命名規範可以大大提高介面的可讀性和可維護性。以下是一些命名規範的…

    編程 2025-04-27
  • 期貨數據介面 Python:打通數字資產交易數據的關鍵

    本文將從以下幾個方面討論期貨數據介面 Python: 一、數據介面簡介 期貨數據介面是指為期貨從業人員提供用於獲取歷史、實時及未來交易數據的工具。Python是一種常用的編程語言,…

    編程 2025-04-27
  • 如何快速發布http介面

    想要快速發布http介面,可以從以下幾個方面入手。 一、選擇合適的框架 選擇合適的框架對於快速發布http介面非常重要。目前比較受歡迎的框架有Flask、Django、Tornad…

    編程 2025-04-27
  • Javaweb 介面返回數據的定義與實現

    本文將介紹 javaweb 如何定義介面返回數據,並提供相應的代碼示例。 一、介面返回數據的定義 在 javaweb 開發中,我們經常需要通過介面返回數據。介面返回的數據格式通常是…

    編程 2025-04-27
  • Postman介面自動化

    一、安裝和使用Postman Postman是一個強大的API測試工具,可以使用它來測試各種類型的API請求和響應。在進行介面自動化測試之前,首先需要安裝和使用Postman。以下…

    編程 2025-04-25

發表回復

登錄後才能評論