作為函數傳回的插件符號
在 Go 中,可以匯入一個外掛程式來實現兩個套件外部定義的通用介面。從插件返回結構時,介面已正確實現。然而,由於 Go 插件系統中的某些技術問題,嘗試直接返回介面會失敗。
原因在於插件符號的性質。當使用 Plugin.Lookup() 從插件中尋找名為 Greeter 的變數時,它會傳回指向該變數的指標。這是允許對插件內的變數進行更改所必需的。
列印 sym 中儲存的值的類型將顯示它是否是指向介面的指標(iface.IPlugin)或實際的介面值 (iface.IPlugin)。在插件回傳struct的情況下,sym中儲存的值是main.testpl類型,它實現了iface.IPlugin,因此類型斷言成功。
但是,當插件回傳iface.IPlugin,sym中儲存的值是*iface.IPlugin類型。這個指向介面值的指標不會直接滿足任何接口,包括iface.IPlugin。因此,型別斷言失敗。
要繞過此問題,可以修改插件以公開返回Greeter 介面而不是全域變數的函數:
func Greeter() iface.IPlugin { return testpl{} }
這將公開名為Greeter 的符號,類型為func() iface.IPlugin。當使用 Plugin.Lookup() 尋找時,它將傳回一個函數指標。這消除了對指向介面值的指標的需要,並允許正確的類型斷言:
greeterFunc, ok := GetFilter.(func() iface.IPlugin) if !ok { panic(errors.New("not of expected type")) } greeter := greeterFunc()
此方法提供了一種更清晰、更一致的方法來公開插件功能,同時避免與直接返回介面相關的陷阱來自插件。
以上是為什麼Go插件無法直接返回接口,如何解決?的詳細內容。更多資訊請關注PHP中文網其他相關文章!