Go 學習筆記 · 進階篇 · 第一天:接口與多態

🐶Go接口與多態:繼承沒了,但自由炸裂!

最近翻 Go 的代碼,突然看到這么一段:

type Animal interface {Speak() string
}

我一愣,咦?這不就是 Java 里常見的“接口”嗎?

錯!錯!錯!

雖然名字一樣,但 Go 的接口,那可是野性自由的靈魂綁定機制。不靠關鍵字、不需要你宣誓,只要你長得像、做得像,它就認你是自己人。


🎯什么是接口?是契約,也是傳說

在 Go 里,接口(interface)是一種類型定義,它只管“你要會什么”,不管“你來自哪”。

🧠 通俗點講:你不用舉手說“我實現了這個接口”,只要你偷偷寫了接口里的方法,你就自動成為合法公民。

來看例子:

type Dog struct{}func (d Dog) Speak() string {return "汪汪!"
}var a Animal = Dog{}
fmt.Println(a.Speak()) // 輸出:汪汪!

注意:你沒寫 implements,也沒繼承誰,甚至沒人發你工牌,就這樣,你就上崗了!

Go:自由之光,照耀你我。


🧩接口的底層結構

interface value
itab(接口表)
具體值 (比如 Dog)
類型信息
方法集合

🧠 小貼士:
接口值其實包含兩個字段:

  • type:值的類型信息
  • value:值的地址或引用

接口只是一個包裝盒,里面放著你這個“具體實現”的身份卡和電話簿。


🎭 多態:同一個接口,不同的實現

比如我再造個喵星人:

type Cat struct{}func (c Cat) Speak() string {return "喵喵~"
}

然后我寫一個函數:

func MakeItSpeak(a Animal) {fmt.Println("動物說話啦:", a.Speak())
}

現在,不管你是狗、貓,甚至程序猿(如果你也實現了 Speak()),通通都能傳進來。

這,就是 Go 的多態靠接口實現,不靠繼承。


🧪 interface{}:萬能膠,還是坑爹罐頭?

interface{} 是“空接口”,所有類型都自動實現它。你傳啥都行:

func PrintAnything(v interface{}) {fmt.Println(v)
}

BUT!你想從這個罐頭里“摳出原型”,得靠類型斷言或者type switch

if s, ok := v.(string); ok {fmt.Println("原來是字符串:", s)
}

或者:

switch val := v.(type) {
case string:fmt.Println("string:", val)
case int:fmt.Println("int:", val)
case Animal:fmt.Println("動物說話:", val.Speak())
default:fmt.Println("unknown type")
}

🎁 有點像開盲盒,有驚喜,也可能是驚嚇。


🎁 接口斷言:打開盲盒的藝術

有時候你拿到的是個接口變量,比如 Animalinterface{},你就像拿到一個包裝好的盲盒。

你知道它里面有“東西”,但不知道具體是什么,這時候就需要——接口斷言

🧙?♂? 單一斷言:你是,我就用!

var a Animal = Dog{}dog, ok := a.(Dog)
if ok {fmt.Println("這是條狗,會說:", dog.Speak())
} else {fmt.Println("斷言失敗,這不是狗")
}

🎯 說明:

  • a.(Dog) 是“斷言”:我相信 a 是 Dog!
  • ok 是“保險”:斷言失敗也不會 panic,而是返回 false

如果你膽子大,不要 ok

dog := a.(Dog) // 如果斷言失敗:panic!

🚨 別問為什么項目突然崩了,問就是 panic。


🔀 類型切換(type switch):一次性拆一箱

你可以用 type switch 來一鍋端多個可能:

func CheckType(v interface{}) {switch val := v.(type) {case string:fmt.Println("是字符串:", val)case int:fmt.Println("是整數:", val)case Animal:fmt.Println("是動物,會說:", val.Speak())default:fmt.Println("未知類型")}
}

🎁 這是 Go 中唯一能在運行時判斷類型的合法方式,配合接口使用非常香!


🧠 接口斷言的兩個注意點:

  1. 只能斷言具體類型或接口類型

    a.(Dog)     ?
    a.(Animal)  ?
    a.(string)  ?(如果 a 是 Animal 類型)
    
  2. 斷言的是“動態類型”,不是靜態的變量類型。

比如:

var a Animal = Dog{}
fmt.Println(a.(Cat)) // ? panic,雖然 a 是 Animal,但不是 Cat

?? 用不好接口,全隊陪你掉坑

Go 的接口用得好,是天使;用得爛,團隊噩夢:

🚫 接口太大:定義一堆方法,結果沒人想實現你。

🚫 濫用 interface{}:Go 變 JS,類型安全?別想了。

🚫 斷言失敗:直接 panic,現場起火🔥

? 最佳實踐

  • 返回接口,接收具體類型”;
  • 盡量定義最小接口,比如:
type Reader interface {Read(p []byte) (n int, err error)
}

這就是經典的 io.Reader只要一個方法,通吃全場。


📝 總結

  • 接口是抽象契約,不靠關鍵字,全靠你“長得像”。
  • 多態靠接口,不靠繼承,寫法簡單,自由優雅。
  • interface{} 是個坑,也可能是奇跡,用之前先畫個防爆圈。
  • Go 接口“隱式實現”,你不用喊“implements”,只要你會做它的事。
  • 斷言是接口盲盒的開封工具,務必加 ok,別 panic!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/77034.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/77034.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/77034.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

信息學奧賽一本通 1929:【04NOIP普及組】火星人 | 洛谷 P1088 [NOIP 2004 普及組] 火星人

【題目鏈接】 ybt 1929&#xff1a;【04NOIP普及組】火星人 洛谷 P1088 [NOIP 2004 普及組] 火星人 【題目考點】 1. 深搜回溯 2. STL next_permutation函數 頭文件<algorithm> 函數定義&#xff1a;next_permutation(lb, ub, cmp) lb&#xff1a;區間下界&#xff…

借助 AI 工具使用 Python 實現北京市店鋪分布地理信息可視化教程

一、項目概述 本項目通過 Python 的pyecharts庫&#xff0c;結合 AI 工具輔助代碼編寫與邏輯梳理&#xff0c;實現北京市店鋪數量分布及區域連線的地理信息可視化&#xff0c;最終生成交互式地圖圖表。 二、準備工作 1. 環境與工具 Python 環境&#xff1a;確保已安裝 Pyth…

Python項目打包指南:PyInstaller與SeleniumWire的兼容性挑戰及解決方案

前言 前段時間做一個內網開發的需求&#xff0c;要求將selenium程序打包成.exe放在內網的win7上運行&#xff0c;在掘金搜了一圈也沒有發現相關文章&#xff0c;因此將過程中踩到的坑記錄分享一下。 本文涵蓋了具體打包操作、不同模塊和依賴項的兼容性解決方案&#xff0c;以…

(一)棧結構、隊列結構

01-線性結構-數組-棧結構 線性結構&#xff08;Linear List)是由n&#xff08;n>0)個數據元素&#xff08;結點&#xff09; a[0], a[1], a[2], a[3],...,a[n-1]組成的有限序列 數組 通常數組的內存是連續的&#xff0c;所以在知道數組下標的情況下&#xff0c;訪問效率是…

【學Rust寫CAD】35 alpha_mul_256(alpha256.rs補充方法)

源碼 // Calculates (value * alpha256) / 255 in range [0,256], // for [0,255] value and [0,256] alpha256. pub fn alpha_mul_256(self,value: u32) -> Alpha256 {let prod value * self.0;Alpha256((prod (prod >> 8)) >> 8) }代碼分析 這個函數 alph…

C# 與 相機連接

一、通過組件連接相機 需要提前在VisionPro里面保存一個CogAcqFifoTool相機工具為 .vpp 定義一個相機工具 CogAcqFifoTool mAcq null;將保存的相機工具放入mAcq中 string path “C:\Acq.vpp”; mAcq (CogAcqFifoTool)CogSerializer.LoadObjectFrommFile(path);給窗口相機…

Java并發編程高頻面試題

一、基礎概念 1. 并行與并發的區別&#xff1f; 并行&#xff1a;多個任務在多個CPU核心上同時執行&#xff08;物理上同時&#xff09;。并發&#xff1a;多個任務在單CPU核心上交替執行&#xff08;邏輯上同時&#xff09;。類比&#xff1a;并行是多個窗口同時服務&#x…

LiT and Lean: Distilling Listwise Rerankers intoEncoder-Decoder Models

文章&#xff1a;ECIR 2025會議 一、動機 背景&#xff1a;利用LLMs強大的能力&#xff0c;將一個查詢&#xff08;query&#xff09;和一組候選段落作為輸入&#xff0c;整體考慮這些段落的相關性&#xff0c;并對它們進行排序。 先前的研究基礎上進行擴展 [14,15]&#xff0c…

Python高級爬蟲之JS逆向+安卓逆向1.2節: 變量與對象

目錄 引言&#xff1a; 1.2.1 Python中的變量 1.2.2 變量的命名與可讀性 1.2.3 Python中的對象 1.2.4 跟大神學高級爬蟲安卓逆向 引言&#xff1a; 大神薯條老師的高級爬蟲安卓逆向教程&#xff1a; 這套爬蟲教程會系統講解爬蟲的初級&#xff0c;中級&#xff0c;高級知…

可發1區的超級創新思路(python 實現):一種輕量化的動態稀疏門控網絡

首先聲明,該模型為原創!原創!原創!且該思路還未有成果發表,感興趣的小伙伴可以借鑒! 一、應用領域 視頻異常檢測、生成視頻檢測。 二、模型解析 該模型由1.關鍵幀動態選擇機制、2.關鍵幀動態選擇機制以及3.關鍵幀動態選擇機制三大核心組件構成,形成端到端的視頻異常…

使用NVM下載Node.js管理多版本

提示&#xff1a;我解決這個bug跟別人思路可能不太一樣&#xff0c;因為我是之前好用&#xff0c;換個項目就不好使了&#xff0c;倦了 文章目錄 前言項目場景一項目場景二解決方案&#xff1a;下載 nvm安裝 nvm重新下載所需Node 版本nvm常用命令 項目結構說明 前言 提示&…

MySQL數據庫經典面試題解析

1. MySQL 索引使用有哪些注意事項呢? 可以從三個維度回答這個問題:索引哪些情況會失效,索引不適合哪些場景,索引規則 索引哪些情況會失效 查詢條件包含or,可能導致索引失效如何字段類型是字符串,where時一定用引號括起來,否則索引失效like通配符可能導致索引失效。聯合…

C#結合SQLite數據庫使用方法

一、關于SQLite SQLite 是一個輕量級的嵌入式關系型數據庫管理系統&#xff08;RDBMS&#xff09;。與傳統的數據庫管理系統&#xff08;如 MySQL、PostgreSQL 或 SQL Server&#xff09;不同&#xff0c;SQLite 并不需要運行單獨的服務器進程&#xff0c;它的數據庫存儲在一個…

深入解析 MySQL 中的日期時間函數:DATE_FORMAT 與時間查詢優化

深入解析 MySQL 中的日期時間函數&#xff1a;DATE_FORMAT 與時間查詢優化 在數據庫管理和應用開發中&#xff0c;日期和時間的處理是不可或缺的一部分。MySQL 提供了多種日期和時間函數來滿足不同的需求&#xff0c;其中DATE_FORMAT函數以其強大的日期格式化能力&#xff0c;…

如何深刻理解Reactor和Proactor

前言&#xff1a; 網絡框架的設計離不開 I/O 線程模型&#xff0c;線程模型的優劣直接決定了系統的吞吐量、可擴展性、安全性等。目前主流的網絡框架&#xff0c;在網絡 IO 處理層面幾乎都采用了I/O 多路復用方案(又以epoll為主)&#xff0c;這是服務端應對高并發的性能利器。 …

筆試專題(七)

文章目錄 乒乓球筐&#xff08;哈希&#xff09;題解代碼 組隊競賽題解代碼 刪除相鄰數字的最大分數&#xff08;線性dp&#xff09;題解代碼 乒乓球筐&#xff08;哈希&#xff09; 題目鏈接 題解 1. 兩個哈希表 先統計第一個字符串中的字符個數&#xff0c;再統計第二個字…

清晰易懂的 Flutter 卸載和清理教程

以下是為 Flutter 徹底卸載與清理教程&#xff0c;覆蓋 Windows、macOS、Linux 系統&#xff0c;步驟清晰無殘留&#xff0c;確保完全刪除 Flutter SDK、依賴工具及 IDE 配置。 一、通用步驟&#xff1a;確認 Flutter 安裝方式 Flutter 通常通過以下方式安裝&#xff1a; 手動…

關于反卷積

&#x1f9e0; 什么是反卷積&#xff1f; 反卷積&#xff08;Deconvolution&#xff09;&#xff0c;通常也稱為轉置卷積&#xff08;Transpose Convolution&#xff09;&#xff0c;是一種用于擴展輸入特征圖的操作&#xff0c;通常用于生成圖像或上采樣任務中。與標準卷積操…

【機器學習】ROC 曲線與 PR 曲線

目錄 一、混淆矩陣&#xff1a;分類評估的基礎 二. ROC 曲線 (Receiver Operating Characteristic Curve) 三. PR 曲線 (Precision-Recall Curve) 3.1 核心思想 4. 何時使用 ROC 曲線和 PR 曲線&#xff1f; 實驗結果 6. 總結 在機器學習的分類任務中&#xff0c;我們訓…

Python高階函數-map

map() 是 Python 內置的一個高階函數&#xff0c;它接收一個函數和一個可迭代對象作為參數&#xff0c;將函數依次作用在可迭代對象的每個元素上&#xff0c;并返回一個迭代器&#xff08;Python 3.x 中&#xff09;。 基本語法 map(function, iterable, ...)function: 應用于…