> go語言接口(interface),類似其他語言的接口的作用,主要用于定義一組函數(方法)簽名,不包括實現。
[TOC]
## 接口定義
> 語法
~~~
type 接口類型名 interface {
? ? 函數簽名列表
}
~~~
> 例子
~~~
// 定義Book接口類型,里面包含一個Abs函數簽名定義,不包括函數實現。
type Book interface {
? ? Abs() float64
}
~~~
## 接口實現
> go語言實現接口,采用的是隱式實現方式,并不像java那樣需要顯示的implement接口,只需實現了接口中的方法,就認為實現了該接口
~~~
package main
import (
"fmt"
)
// 定義Book接口類型,里面包含一個Abs函數簽名定義,不包括函數實現
type Book interface {
Abs() float64
}
// 定義一個MyFloat類型,它是float64的別名
type MyFloat float64
// 給MyFloat類型,定義一個Abs方法,計算絕對值
func (f MyFloat) Abs() float64 {
if f < 0 {
return float64(-f)
}
return float64(f)
}
// 定義ArtBook類型結構體
type ArtBook struct {
Price1, Price2 float64
}
// 為ArtBook類型定義Abs方法
func (book *ArtBook) Abs() float64 {
return book.Price1 + book.Price2
}
func main() {
// 定義Book接口變量
var book Book
// 定義MyFloat類型變量
f := MyFloat(-100.25)
// 因為MyFloat實現了,Book接口中定義的方法,所以可以賦值給接口類型變量
book = f
// 通過接口類型調用方法
fmt.Println(book.Abs())
// 定義ArtBook類型變量
v := ArtBook{Price1: 11, Price2: 20}
// 將ArtBook變量賦值給接口類型,這里之所以需要取地址符,因為*ArtBook類型實現了接口的Abs方法
book = &v
// 通過接口類型調用方法
fmt.Println(book.Abs())
}
~~~
> MyFloat和ArtBook并沒有顯式的說明實現Book接口,只要實現了Book接口的方法,就認為實現了該接口
## 接口變量默認值
> 沒有初始化的接口變量,默認值是nil
~~~
var book Book
if book == nil {
fmt.Println("is nil")
}
fmt.Println(book)
~~~
## 空接口
> 包含0個方法的接口,就是空接口,如下
~~~
interface{}
~~~
### 空接口類型
> 空接口類型可以存儲任意類型的數據,類似java的object類型
```
package main
import "fmt"
func main() {
// 定義空接口變量
var obj interface{}
// 賦值一個Int類型數據給空接口
obj = 42
fmt.Println(obj)
// 再賦值一個string類型數據給空接口
obj = "hello"
fmt.Println(obj)
}
```
### interface類型轉換
> 轉換語法:i 是interface{}類型變量,T是我們要轉換的類型
```
t := obj.(要轉換的類型)
```
> 例子
> 注意:interface{}類型轉換,只能轉換至真實的類型,通俗的講就是,當初賦值給interface{}變量的是什么類型數據,就只能還原成什么類型數據
```
// 定義一個interface{}類型,并初始化為字符串
var obj interface{} = "hello"
// 轉換成string類型
s := obj.(string)
```
### 判斷Interface類型轉換失敗
> 語法:通過第二個返回值ok判斷是否轉換成功
```
value, ok := obj.(要轉換的類型)
```
> 例子
```
var obj interface{} = "hello"
str, ok := obj.(string)
```
### interface類型判斷
> 通過switch語句結合i.(type)語法,判斷interface類型
```
package main
import "fmt"
func do(obj interface{}) {
// 通過switch判斷i的類型
switch v := obj.(type) {
case int:
fmt.Println("是int類型,", v)
case string:
fmt.Println("是string類型,", v)
default:
fmt.Println("未知類型,", v)
}
}
func main() {
do(21)
do("hello")
do(true)
}
```
- 基礎知識
- 開發環境
- 包名規則
- 包初始化 (init)
- 基礎數據類型
- 基礎類型轉換
- 格式化輸出
- go指針
- 流程控制語句
- 函數定義
- 匿名函數
- 數組和切片
- map集合
- 結構體
- Interface接口
- 日期處理
- 數學計算
- 正則表達式
- 協程 (并發處理)
- channel
- waitgroup
- mutex (鎖機制)
- websocket
- protobuf
- Redis
- 錯誤處理
- 打包程序
- NSQ消息隊列
- 單元測試
- beego
- 安裝入門
- Gin
- 快速入門
- 路由與控制器
- 處理請求參數
- 表單驗證
- 處理響應結果
- 渲染HTML模版
- 訪問靜態文件
- Gin中間件
- Cookie處理
- Session處理
- Gin上傳文件
- swagger
- pprof性能測試
- GORM
- 入門教程
- 模型定義
- 數據庫連接
- 插入數據
- 查詢數據
- 更新數據
- 刪除數據
- 事務處理
- 關聯查詢
- 屬于 (BELONG TO)
- 一對一 (Has One)
- 一對多 (Has Many)
- 多對多 (Many to Many)
- 預加載 (Preloading)
- 錯誤處理
- 第三方常用插件
- viper 讀取配置文件
- zap 高性能日志
- Nginx代理配置
- Goland 快捷鍵