【Go語言基礎【19】】接口:靈活實現多態的核心機制

文章目錄

  • 零、概述
  • 一、接口基礎
    • 1、接口的基本概念
      • a. 接口定義
      • b. 類型實現接口(無需顯式聲明)
      • c. 接口變量(體現了多態)
    • 2、實現接口的方式
    • 3、接口組合
    • 4、接口的底層結構
  • 二、空接口與類型斷言
    • 1. 空接口(`interface{}`):接口類型的變量
    • 2. 類型斷言:推斷底層類型
    • 3. 類型開關(Type Switch)
  • 三、接口的應用場景
    • 1. 多態
    • 2. 依賴注入

零、概述

Go語言的接口(Interface)是一種抽象類型,用于定義一組方法的簽名(即方法名、參數和返回值),但不包含方法的實現。接口是Go語言實現多態的核心機制,允許不同類型通過實現相同接口來表現出統一的行為。

Go的接口設計遵循**“鴨子類型”(Duck Typing)**原則:“如果它走路像鴨子,叫聲像鴨子,那么它就是鴨子”。這種隱式實現方式使代碼更靈活、松耦合,同時保持類型安全。通過合理使用接口,可以構建出可擴展、易維護的Go程序。

接口的注意事項

  1. 接口嵌套循環 接口不能直接或間接嵌套自身,否則會導致編譯錯誤。
  2. 性能開銷 接口調用涉及動態分發,比直接調用方法略慢(通常可忽略不計)。
  3. 避免過度抽象 僅在必要時使用接口,避免為簡單場景引入過多抽象層。

?

一、接口基礎

1、接口的基本概念

a. 接口定義

type Animal interface {Speak() string  // 方法簽名,無實現Move() string
}

b. 類型實現接口(無需顯式聲明)

若類型(如結構體)實現了接口中的所有方法,則該類型自動實現了此接口,無需顯式聲明。

type Dog struct{}
func (d Dog) Speak() string { return "Woof!" }
func (d Dog) Move() string  { return "Run" }type Cat struct{}
func (c Cat) Speak() string { return "Meow!" }
func (c Cat) Move() string  { return "Jump" }

c. 接口變量(體現了多態)

接口類型的變量可以存儲任何實現了該接口的類型的值,體現了多態的思想。

package main// 定義接口
type Speaker interface {Speak() string
}// 結構體Dog實現了Speaker接口
type Dog struct{}func (d Dog) Speak() string { return "Woof!" }// 結構體Cat也實現了Speaker接口
type Cat struct{}func (c Cat) Speak() string { return "Meow!" }func main() {var s Speaker      // 聲明一個接口類型的變量s = Dog{}          // 存儲Dog類型的值(因為Dog實現了Speaker)println(s.Speak()) // 輸出: "Woof!"s = Cat{}          // 存儲Cat類型的值(因為Cat也實現了Speaker)println(s.Speak()) // 輸出: "Meow!"
}

?

2、實現接口的方式

a. 隱式實現 :無需顯式聲明類型實現了某個接口,只需實現接口中的所有方法。

b. 方法集規則

  • 值接收者方法T*T類型均實現該接口。
  • 指針接收者方法:僅*T類型實現該接口(需顯式取地址)。
   type Mover interface {Move()}type Car struct{}func (c Car) Move() {}  // 值接收者方法,Car和*Car均實現Movertype Bike struct{}func (b *Bike) Move() {}  // 指針接收者方法,僅*Bike實現Movervar m Moverm = Car{}      // 合法m = &Bike{}    // 必須顯式取地址// m = Bike{}   // 錯誤:Bike未實現Mover

?

3、接口組合

接口可通過組合其他接口形成新接口。

type Reader interface {Read(p []byte) (n int, err error)
}type Writer interface {Write(p []byte) (n int, err error)
}// 組合Reader和Writer
type ReadWriter interface {ReaderWriter
}

?

4、接口的底層結構

a. 接口變量在底層由兩個字段組成:1. 動態類型(Type):存儲實際值的類型、2. 動態值(Data):存儲實際值的副本或指針。
b. 對于包含方法的接口(如Animal),Go使用itab(接口表)來關聯接口方法和實際類型的方法實現。

?

二、空接口與類型斷言

1. 空接口(interface{}):接口類型的變量

空接口不包含任何方法,所有類型都實現了空接口,因此可存儲任意類型的值。

var x interface{}
x = 42          // 存儲int
x = "hello"     // 存儲string

?

2. 類型斷言:推斷底層類型

在 Go 語言中,類型斷言(Type Assertion)是一種用于從接口值(interface)中提取其底層實際類型值的機制。比如:當你有一個接口變量時,有時需要知道它底層實際存儲的是什么類型,并提取該類型的值。這時就需要使用類型斷言。

語法結構

value, ok := interfaceVar.(TargetType)- interfaceVar:接口類型的變量。
- TargetType:你想要斷言的目標類型。
- value:提取出的 TargetType 類型的值。
- ok:布爾值,表示斷言是否成功(安全斷言時使用)。
	var x interface{} = 42 // x 存儲了 int 類型的值// 安全斷言if v, ok := x.(int); ok {fmt.Println("x is int:", v) // 輸出: x is int: 42}// 非安全斷言(類型匹配時)v := x.(string) // interface {} is int, not stringfmt.Println(v)  // 輸出: 42

?

3. 類型開關(Type Switch)

批量判斷接口值的實際類型。

switch v := x.(type) {
case int:fmt.Println("x is int")
case string:fmt.Println("x is string")
default:fmt.Println("unknown type")
}

?

三、接口的應用場景

1. 多態

通過接口實現不同類型的統一行為。

func PrintAnimal(a Animal) {fmt.Println(a.Speak(), a.Move())
}PrintAnimal(Dog{})   // 輸出: "Woof! Run"
PrintAnimal(Cat{})   // 輸出: "Meow! Jump"

?

2. 依賴注入

通過接口解耦組件間的依賴關系。

type Logger interface {Log(msg string)
}type FileLogger struct{}
func (f FileLogger) Log(msg string) { /* 實現日志寫入文件 */ }func ProcessData(l Logger) {l.Log("Processing data...")
}ProcessData(FileLogger{})  // 注入文件日志實現

?

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

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

相關文章

Linux文件管理和輸入輸出重定向

文件管理 Bash執行命令 passwd passwd普通用戶修改密碼 passwd robinkoolroot用戶管理賬戶密碼 passwd -d robinkoolroot用戶刪除普通用戶密碼 file file /bin/filecat cat option 文件 cat -A /etc/hosts #-A選項等于-VETcat /etc/hosts /etc/fstab一次性查看多個文件…

檢查項目中的依賴是否有更新——npm outdated

項目中輸入 npm outdated如果出現package紅色 則是需要更新的插件 更新最新的插件 使用latest下面的版本 Package Current Wanted Latest Location 包的名字 項目當前的版本 ... 需要更新到的版本然后將Latest的版本復制到pakcea…

vSphere環境ubuntu24.04虛擬機從BIOS切換為EFI模式啟動

文章目錄 一、操作背景二、操作步驟1.配置本地鏡像倉庫(可選)2.確認當前分區是gpt分區3.創建EFI分區4.安裝和修改GRUB5.重啟配置生效 三、驗證EFI模式方法 1:檢查 /sys/firmware/efi 目錄方法 2:檢查 dmesg 啟動日志方法 3:使用 efibootmgr&a…

python打卡day48

import torch # 生成一個3x3的標準正態分布隨機張量 random_tensor torch.randn(3, 3) print("隨機張量:\n", random_tensor) 隨機張量: tensor([[-0.9343, -0.3254, 0.6991], [-1.7157, 1.7171, -0.4322], [ 0.6004, -1.1050, -0.2178]]) # …

推薦算法八股總結

從計算機視覺轉行搜廣推的第9天 1.youtubednn 推薦系統經典模型YouTubeDNN_推薦系統架構圖-CSDN博客文章瀏覽閱讀2.1k次,點贊28次,收藏34次。本文詳細介紹了YouTubeDNN推薦系統,包括其召回階段的多模型篩選策略,排序階段的復雜模…

EasyRTC音視頻實時通話功能在WebRTC與智能硬件整合中的應用與優勢

一、WebRTC與智能硬件整合趨勢? 隨著物聯網和實時通信需求的爆發式增長,WebRTC作為開源實時通信技術,為瀏覽器與移動應用提供免插件的音視頻通信能力,在智能硬件領域的融合應用已成必然趨勢。智能硬件不再局限于單一功能,對實時…

零基礎在實踐中學習網絡安全-皮卡丘靶場(第九期-Unsafe Fileupload模塊)(yakit方式)

本期內容并不是很難,相信大家會學的很愉快,當然對于有后端基礎的朋友來說,本期內容更加容易了解,當然沒有基礎的也別擔心,本期內容會詳細解釋有關內容 本期用到的軟件:yakit(因為經過之前好多期…

生信服務器 | 做生信為什么推薦使用Linux服務器?

原文鏈接:生信服務器 | 做生信為什么推薦使用Linux服務器? 原文鏈接:生信服務器 | 做生信為什么推薦使用Linux服務器? ---- 原文鏈接:生信服務器 | 做生信為什么推薦使用Linux服務器? ---- 原文鏈…

OpenCV 圖像色彩空間轉換與摳圖

一、知識點: 1、色彩空間轉換函數 (1)、void cvtColor( InputArray src, OutputArray dst, int code, int dstCn 0, AlgorithmHint hint cv::ALGO_HINT_DEFAULT ); (2)、將圖像從一種顏色空間轉換為另一種。 (3)、參數說明: src: 輸入圖像,即要進行顏…

高斯列主元消去法——python實現

高斯列主元消去法 1. 高斯消去法 高斯消去法是一種求解線性方程組 A x b A\mathbf{x} \mathbf{b} Axb 的方法,通過逐步化簡增廣矩陣,將其變為上三角矩陣,從而方便求解未知數。 線性方程組的一般形式為: { a 11 x 1 a 12 x…

linux下安裝elasticsearch及ik分詞器

linux下安裝elasticsearch及ik分詞器 安裝版本 linux版本:centos7.5 es版本:elasticsearch-7.14.0-linux-x86_64.tar.gz 下載地址:https://www.elastic.co/downloads/past-releases#elasticsearch Ik版本:elasticsearch-analysi…

相機Camera日志分析之三十一:高通Camx HAL十種流程基礎分析關鍵字匯總(后續持續更新中)

【關注我,后續持續新增專題博文,謝謝!!!】 上一篇我們講了:有對最普通的場景進行各個日志注釋講解,但相機場景太多,日志差異也巨大。后面將展示各種場景下的日志。 通過notepad++打開場景下的日志,通過下列分類關鍵字搜索,即可清晰的分析不同場景的相機運行流程差異…

【配置篇】告別硬編碼:多環境配置、@ConfigurationProperties與配置中心初探

摘要 本文是《Spring Boot 實戰派》系列的第五篇,聚焦于企業級應用開發中至關重要的配置管理。文章將首先解決開發、測試、生產環境配置不同的痛點,詳細介紹 Spring Boot 的 Profile(多環境配置) 機制。接著,我們將深…

代碼隨想錄算法訓練營第60期第六十三天打卡

大家好,我們昨天講解的是拓撲排序與Dijkstra算法的樸素版,其實我們大致了解了兩種算法的代碼實現,我們通過上次博客了解到拓撲排序其實是可以判斷圖里是否存在環,而Dijkstra算法則使用于非負邊權最短路的求解,今天我們…

linux中如何在日志里面檢索nowStage不等于1的數據的指令

你想在 Linux 中查找日志文件中 nowStage 不等于 1 的所有 JSON 行,當前你已經使用了: Bash 深色版本 grep -rn "nowStage" ./ 這個命令可以找到包含 "nowStage" 字樣的所有行及其所在的文件名和行號,但還不能篩選出 no…

【習題】DevEco Studio的使用

判斷題 1. 如果代碼中涉及到一些網絡、數據庫、傳感器等功能的開發,均可使用預覽器進行預覽。 正確(True) 錯誤(False) 正確答案: 錯誤(False) 知識點 預覽器的使用。解析:預覽器只支持對頁面的預覽,如果代碼中涉及到一些網絡、數據庫、…

SpringBoot實現簡易直播

當下直播技術已經成為各類應用不可或缺的一部分,從社交媒體到在線教育,再到電子商務和游戲領域,直播功能正在被廣泛應用。 本文將介紹如何使用SpringBoot框架構建一個直播流推拉系統。 一、直播技術基礎 1.1 推流與拉流概念 直播系統的核心…

xcode 各版本真機調試包下載

下載地址 https://github.com/filsv/iOSDeviceSupport 使用方法: 添加到下面路徑中,然后退出重啟xcode /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport

DL00871-基于深度學習YOLOv11的盲人障礙物目標檢測含完整數據集

基于深度學習YOLOv11的盲人障礙物目標檢測:開啟盲人出行新紀元 在全球范圍內,盲人及視覺障礙者的出行問題一直是社會關注的重點。盡管技術不斷進步,許多城市的無障礙設施依然未能滿足盲人出行的實際需求。尤其是在復雜的城市環境中&#xff…

Python 訓練 day46

知識點回顧: 不同CNN層的特征圖:不同通道的特征圖什么是注意力:注意力家族,類似于動物園,都是不同的模塊,好不好試了才知道。通道注意力:模型的定義和插入的位置通道注意力后的特征圖和熱力圖 作…