溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Go語言中的空接口的詳細(xì)解析

發(fā)布時間:2020-07-17 15:18:42 來源:億速云 閱讀:326 作者:小豬 欄目:編程語言

這篇文章主要講解了Go語言中的空接口的詳細(xì)解析,內(nèi)容清晰明了,對此有興趣的小伙伴可以學(xué)習(xí)一下,相信大家閱讀完之后會有幫助。

1. 什么是空接口?

空接口是特殊形式的接口類型,普通的接口都有方法,而空接口沒有定義任何方法口,也因此,我們可以說所有類型都至少實(shí)現(xiàn)了空接口。

type empty_iface interface {
}

每一個接口都包含兩個屬性,一個是值,一個是類型。

而對于空接口來說,這兩者都是 nil,可以使用 fmt 來驗(yàn)證一下

package main

import (
	"fmt"
)

func main() {
	var i interface{}
	fmt.Printf("type: %T, value: %v", i, i)
}

輸出如下

type: <nil>, value: <nil>

2. 如何使用空接口?

第一,通常我們會直接使用 interface{} 作為類型聲明一個實(shí)例,而這個實(shí)例可以承載任意類型的值。

package main

import (
	"fmt"
)

func main() {
	// 聲明一個空接口實(shí)例
	var i interface{}

	// 存 int 沒有問題
	i = 1
	fmt.Println(i)

	// 存字符串也沒有問題
	i = "hello"
	fmt.Println(i)

	// 存布爾值也沒有問題
	i = false
	fmt.Println(i)
}

第二,如果想讓你的函數(shù)可以接收任意類型的值 ,也可以使用空接口

接收一個任意類型的值 示例

package main

import (
	"fmt"
)

func myfunc(iface interface{}){
	fmt.Println(iface)
}

func main() {
	a := 10
	b := "hello"
	c := true

	myfunc(a)
	myfunc(b)
	myfunc(c)
}

接收任意個任意類型的值 示例

package main

import (
	"fmt"
)

func myfunc(ifaces ...interface{}){
	for _,iface := range ifaces{
		fmt.Println(iface)
	}
}

func main() {
	a := 10
	b := "hello"
	c := true

	myfunc(a, b, c)
}

第三,你也定義一個可以接收任意類型的 array、slice、map、strcut,例如這邊定義一個切片

package main

import "fmt"

func main() {
 any := make([]interface{}, 5)
 any[0] = 11
 any[1] = "hello world"
 any[2] = []int{11, 22, 33, 44}
 for _, value := range any {
 fmt.Println(value)
 }
}

3. 空接口幾個要注意的坑

坑1:空接口可以承載任意值,但不代表任意類型就可以承接空接口類型的值

從實(shí)現(xiàn)的角度看,任何類型的值都滿足空接口。因此空接口類型可以保存任何值,也可以從空接口中取出原值。

但要是你把一個空接口類型的對象,再賦值給一個固定類型(比如 int, string等類型)的對象賦值,是會報(bào)錯的。

package main

func main() {
	// 聲明a變量, 類型int, 初始值為1
	var a int = 1

	// 聲明i變量, 類型為interface{}, 初始值為a, 此時i的值變?yōu)?
	var i interface{} = a

	// 聲明b變量, 嘗試賦值i
	var b int = i
}

這個報(bào)錯,它就好比可以放進(jìn)行禮箱的東西,肯定能放到集裝箱里,但是反過來,能放到集裝箱的東西就不一定能放到行禮箱了,在 Go 里就直接禁止了這種反向操作。(聲明:底層原理肯定還另有其因,但對于新手來說,這樣解釋也許會容易理解一些。)

.\main.go:11:6: cannot use i (type interface {}) as type int in assignment: need type assertion

坑2::當(dāng)空接口承載數(shù)組和切片后,該對象無法再進(jìn)行切片

package main

import "fmt"

func main() {
	sli := []int{2, 3, 5, 7, 11, 13}

	var i interface{}
	i = sli

	g := i[1:3]
	fmt.Println(g)
}

執(zhí)行會報(bào)錯。

.\main.go:11:8: cannot slice i (type interface {})

坑3:當(dāng)你使用空接口來接收任意類型的參數(shù)時,它的靜態(tài)類型是 interface{},但動態(tài)類型(是 int,string 還是其他類型)我們并不知道,因此需要使用類型斷言。

package main

import (
	"fmt"
)

func myfunc(i interface{}) {

	switch i.(type) {
	case int:
		fmt.Println("參數(shù)的類型是 int")
	case string:
		fmt.Println("參數(shù)的類型是 string")
	}
}

func main() {
	a := 10
	b := "hello"
	myfunc(a)
	myfunc(b)
}

輸出如下

參數(shù)的類型是 int
參數(shù)的類型是 string

看完上述內(nèi)容,是不是對Go語言中的空接口的詳細(xì)解析有進(jìn)一步的了解,如果還想學(xué)習(xí)更多內(nèi)容,歡迎關(guān)注億速云行業(yè)資訊頻道。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

go
AI