欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Go語言斷言和類型查詢的實現(xiàn)

 更新時間:2024年01月30日 10:45:35   作者:242030  
Go語言變量類型包含基礎類型和復合類型,類型斷言一般是對基礎類型的處理,本文主要介紹了Go語言斷言和類型查詢的實現(xiàn),感興趣的可以了解一下

1、類型斷言

類型斷言(Type Assertion)是一個使用在接口值上的操作,用于檢查接口類型變量所持有的值是否實現(xiàn)了期望的接口或者具體的類型。

在Go語言中類型斷言的語法格式如下:

// i.(TypeNname)
value, ok := x.(T)

其中,x 表示一個接口的類型,如果是具體類型變量,則編譯器會報non-interface type xxx on left,T 表示一個具體的類型(也可為接口類型)。

該斷言表達式會返回 x 的值(也就是 value)和一個布爾值(也就是 ok),可根據該布爾值判斷 x 是否為 T 類型:

  • 如果 T 是具體某個類型,類型斷言會檢查 x 的動態(tài)類型是否等于具體類型 T。如果檢查成功,類型斷言返回的結果是 x 的動態(tài)值,其類型是 T。

  • 如果 T 是接口類型,類型斷言會檢查 x 的動態(tài)類型是否滿足 T。如果檢查成功,x 的動態(tài)值不會被提取,返回值是一個類型為 T 的接口值。

  • 無論 T 是什么類型,如果 x 是 nil 接口值,類型斷言都會失敗。

示例代碼如下:

package main

import (
	"fmt"
)

func main() {
	var x interface{}
	x = 10
	value, ok := x.(int)
	// 10,true
	fmt.Print(value, ",", ok)
}

運行結果如下:

# 程序結果
10,true

需要注意如果不接收第二個參數也就是上面代碼中的 ok,斷言失敗時會直接造成一個 panic,如果 x 為 nil 同樣也會 panic。

示例代碼如下:

package main

import (
	"fmt"
)

func main() {
	var x interface{}
	x = "Hello"
	value := x.(int)
	fmt.Println(value)
}

運行結果如下:

# 輸出結果
panic: interface conversion: interface {} is string, not int

接口斷言通??梢允褂?comma,ok 語句來確定接口是否綁定某個實例類型,或者判斷接口綁定的實例類型是否實現(xiàn)另一個接口。

re,ok := body.(io.ReadCloser)
if,ok :=  r.Body.(*maxBytesReader);

2、類型查詢

接口類型查詢的語法格式如下:

switch v := i.(type){
	case typel:
		XXXX
	case type2:
		XXXX
	default:
		XXXX
}

接口查詢有兩層語義,一是查詢一個接口變量底層綁定的底層變量的具體類型是什么,二是查詢接口變量綁定的底

層變量是否還實現(xiàn)了其他接口。

(1)、i 必須是接口類型

具體類型實例的類型是靜態(tài)的,在類型聲明后就不再變化,所以具體類型的變量不存在類型查詢,類型查詢一定是

對一個接口變量進行操作。也就是說,上文中的i必須是接口變量,如果i是未初始化接口變量,則v的值是 nil。

package main

import (
	"fmt"
	"io"
)

func main() {
	var i io.Reader
	//此處i是為未初始化的接口變量,所以v為nil
	switch v := i.(type) {
	case nil:
		//<nil>
		fmt.Printf("%T\n", v)
	default:
		fmt.Printf("default")
	}
}

(2)、case 字句后面可以跟非接口類型名,也可以跟接口類型名,匹配是按照 case 子句的順序進行的。

  • 如果 case 后面是一個接口類型名,且接口變量i綁定的實例類型實現(xiàn)了該接口類型的方法,則匹配成,v的類型是接口類型,v底層綁定的實例是i綁定具體類型實例的副本。

  • 如果 case 后面是一個具體類型名,且接口變量i綁定的實例類型和該具體類型相同,則匹配成功,此時v 就是該具體類型變量,v的值是i綁定的實例值的副本。

  • 如果 case 后面跟著多個類型,使用逗號分隔,接口變量i綁定的實例類型只要和其中一個類型匹配,則直接使用o賦值給v,相當于 v:=o。這個語法有點奇怪,按理說編譯器不應該允許這種操作,語言實現(xiàn)者可能想讓type switch 語句和普通的 switch 語句保持一樣的語法規(guī)則,允許發(fā)生這種情況。

  • 如果所有的case字句都不滿足,則執(zhí)行 default 語句,此時執(zhí)行的仍然是 v:=o,最終v的值是o。此時使用v沒有任何意義。

  • fallthrough 語句不能在 Type Switch 語句中使用。

package main

import (
	"fmt"
	"io"
	"log"
	"os"
)

func main() {
	var i io.Reader
	// 此處i是為未初始化的接口變量,所以v為nil
	switch v := i.(type) {
	case nil:
		// <nil>
		fmt.Printf("%T\n", v)
	default:
		fmt.Printf("default")
	}
	f, err := os.OpenFile("notes.txt", os.O_RDWR|os.O_CREATE, 0755)
	if err != nil {
		log.Fatal(err)
	}
	defer f.Close()
	i = f
	switch v := i.(type) {
	// i的綁定的實例是*osFile類型,實現(xiàn)了io.ReadWriter接口,所以下面case匹配成功
	case io.ReadWriter:
		// v是io.ReadWriter接口類型,所以可以調用Write方法
		v.Write([]byte("io.ReadWriter\n"))
		// Type Switch Result: io.ReadWriter
		fmt.Println("Type Switch Result: io.ReadWriter")
	// 由于上一個case已經匹配,就算這個case也匹配,也不會走到這里
	case *os.File:
		v.Write([]byte("*os.File\n"))
		fmt.Println("Type Switch Result: *os.File")
		//這里可以調用具體類型方法
		v.Sync()
	default:
		fmt.Println("Type Switch Result: unknown")
		return
	}

	switch v := i.(type) {
	// 匹配成功,v的類型就是具體類型*os.File
	case *os.File:
		v.Write([]byte("*os.File\n"))
		// Type Switch Result: *os.File
		fmt.Println("Type Switch Result: *os.File")
		v.Sync()
	//由于上一個case已經匹配,就算這個case也匹配,也不會走到這里
	case io.ReadWriter:
		//v是io.ReadWriter接口類型,所以可以調用Write方法
		v.Write([]byte("io.ReadWriter\n"))
		fmt.Println("Type Switch Result: io.ReadWriter")
	default:
		fmt.Println("Type Switch Result: unknown")
		return
	}

	switch v := i.(type) {
	//多個類型,f滿足其中任何一個就算匹配
	case *os.File, io.ReadWriter:
		// 此時相當于執(zhí)行力v := i ,v和i是等價的,使用v沒有意義。
		if v == i {
			// true
			fmt.Println(true)
		}
	default:
		return
	}
}

# 程序輸出
<nil>
Type Switch Result: io.ReadWriter
Type Switch Result: *os.File
true 

package main

import (
	"fmt"
)

func main() {
	var a int
	a = 10
	// the type of a is int
	getType(a)
}

func getType(a interface{}) {
	switch a.(type) {
	case int:
		fmt.Println("the type of a is int")
	case string:
		fmt.Println("the type of a is string")
	case float64:
		fmt.Println("the type of a is float")
	default:
		fmt.Println("unknown type")
	}
}

# 程序輸出
the type of a is int

 到此這篇關于Go語言斷言和類型查詢的實現(xiàn)的文章就介紹到這了,更多相關Go語言斷言和類型查詢內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

您可能感興趣的文章:

相關文章

  • Go語言安裝和GoLand2021最全超詳細安裝教程

    Go語言安裝和GoLand2021最全超詳細安裝教程

    Go語言和GoLand的關系好比于java和idea、python和pycharm,因此我們需要先安裝好Go語言后才能安裝GoLand。它的安裝和java,python的安裝大同小異,好了,下面給大家?guī)砹薌oLand2021安裝教程,需要的朋友參考下吧
    2021-08-08
  • Go高級特性探究之優(yōu)先級隊列詳解

    Go高級特性探究之優(yōu)先級隊列詳解

    Heap?是一種數據結構,這種數據結構常用于實現(xiàn)優(yōu)先隊列,這篇文章主要就是來和大家深入探討一下GO語言中的優(yōu)先級隊列,感興趣的可以了解一下
    2023-06-06
  • Go 語言中靜態(tài)類型和動態(tài)類型的使用

    Go 語言中靜態(tài)類型和動態(tài)類型的使用

    本文主要介紹了Go語言中的靜態(tài)類型和動態(tài)類型,靜態(tài)類型在編譯時確定,提供了類型安全,性能優(yōu)化和代碼清晰,而動態(tài)類型在運行時確定,提供了更高的靈活性,但可能引發(fā)運行時錯誤,下面就來介紹一下,感興趣的可以了解一下
    2024-10-10
  • Go??iota?常量基本語法介紹

    Go??iota?常量基本語法介紹

    這篇文章主要介紹了Go?為什么要設計?iota?常量,我們介紹了 Go 中 iota 的基本語法。同時基于歷史資料針對 iota 到底是什么,為什么要這么叫,又有什么用進行了一番研究,需要的朋友可以參考下
    2022-06-06
  • Golang中HTTP路由設計的使用與實現(xiàn)

    Golang中HTTP路由設計的使用與實現(xiàn)

    這篇文章主要介紹了Golang中HTTP路由設計的使用與實現(xiàn),為什么要設計路由規(guī)則,因為路由規(guī)則是HTTP的請求按照一定的規(guī)則 ,匹配查找到對應的控制器并傳遞執(zhí)行的邏輯,需要的朋友可以參考下
    2023-05-05
  • go語言base64加密解密的方法

    go語言base64加密解密的方法

    這篇文章主要介紹了go語言base64加密解密的方法,實例分析了Go語言base64加密解密的技巧,需要的朋友可以參考下
    2015-03-03
  • Go 切片導致內存泄露的幾種原因

    Go 切片導致內存泄露的幾種原因

    某些情況下,對一個已存在的切片或數組進行切分操作可能會導致內存泄漏,本文主要介紹了Go 切片導致內存泄露的幾種原因,感興趣的可以了解一下
    2023-05-05
  • Go語言開發(fā)前后端不分離項目詳解

    Go語言開發(fā)前后端不分離項目詳解

    這篇文章主要為大家介紹了Go語言開發(fā)前后端不分離項目詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-11-11
  • golang?Gorm框架講解

    golang?Gorm框架講解

    gorm是一個使用Go語言編寫的ORM框架,這篇文章主要介紹了golang?Gorm框架,本文通過示例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-12-12
  • golang 生成定單號的操作

    golang 生成定單號的操作

    這篇文章主要介紹了golang 生成定單號的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12

最新評論