x.(t)
檢查x的動態型別是否是t,其中x必須是介面值。
* 如果t是具體型別
型別斷言檢查x的動態型別是否等於具體型別t。如果檢查成功,型別斷言返回的結果是x的動態值,其型別是t。換句話說,對介面值x斷言其動態型別是具體型別t,若成功則提取出x的具體值。如果檢查失敗則panic。
例如:
var w io.writer
w = os.stdout 是乙個型別為*os.file的包級別變數
f := w.(*os.file) //斷言介面w的動態型別是具體型別*os.file,斷言成功,返回os.stdout給f
c := w.(*bytes.buffer) //斷言介面w的動態型別是具體型別*bytes.buffer,斷言失敗,panic
var w io.writer
w = os.stdout
rw := w.(io.readwriter) //成功:*os.file同時有read和write方法
w = new(bytecounter) //有write方法
rw = w.(io.readwriter) // panic: *bytecounter沒有read方法
w = rw // io.readwriter賦值給io.writer
w = rw.(io.writer) //和上面一樣,僅當rw為nil時失敗,而上面如果rw為nil則w被賦值為nil
如果我們想知道型別斷言是否失敗,而不是失敗時觸發panic,可以使用返回兩個值的版本:
y, ok :=x.(t)
當檢查成功時ok為true。例如:
var w io.writer = os.stdout
f, ok := w.(*os.file) //成功:f為os.stdout,ok為true
b, ok := w.(*bytes.buffer) //失敗:b為零值,這裡是nil, ok為false,no panic
if f, ok := w.(*os.file); ok
型別斷言用於查詢可能的行為,例子:
package main
import (
"io"
"os"
)//這個例子展示了型別斷言用於選擇可能的行為,這兒如果乙個io.writer支援writestring則可以直接使用,從而避免分配臨時記憶體
func writestring(w io.writer, s string) (n int, err error)
if sw, ok := w.(stringwriter); ok
return w.write(byte(s)) // allocate temporary copy
}func writeheader(w io.writer, contenttype string) error
if _, err := io.writestring(w, contenttype); err != nil
return
nil}
func main()
switch x.(type)
//case的順序是有意義的,因為可能同時滿足多個介面,不可以用fallthrough, default的位置無所謂。
如果需要提取具體的值:
switch x := x.(type) //前面的x是乙個區域性變數,因為switch建立了乙個詞法域
//x的型別就是每個case的型別,如果case有多個型別,則型別為inte***ce{}
Go語言型別轉換和型別斷言
型別轉換在編譯期完成,包括強制轉換和隱式轉換 型別斷言在執行時確定,包括安全型別斷言和非安全型別斷言 go語言要求不同型別之間必須做顯式的型別轉換。但似乎涉及到介面型別時,就會有所不同。兩種型別斷言 不安全的型別斷言,如果系統檢測到不匹配,會在執行時呼叫內建的panic,丟擲異常 s abc i s...
Go型別斷言
package main import fmt 型別斷言 type assertion 是乙個使用在介面值上的操作,用於檢查介面型別變數所持有的值是否實現了期望的介面或者具體的型別。如何進行型別斷言的判斷?1.使用if語句或者switch語句 2.依靠 value,ok x.t x 表示乙個介面的型...
GO語言使用之型別斷言
型別斷言,由於介面是一般型別,不知道具體型別,如果要轉成具體型別,就需要使用型別斷言 型別斷言 func typeassertion x t ok 待檢測的型別斷言 y res x.float32 if res else y1 res1 x.int32 轉成float if res1 else 1 ...