Type Assertion
---
```go
import (
"log"
"fmt"
)
type conversion: change type assertion: reveal
Conversion example
type MyInt int
func main() {
var i MyInt = 20
i2 := int(i)
fmt.Println(i2)
}
20
Assertion example (happens at runtime), always check type assertions!
func main() {
var i interface{}
var mine MyInt = 20
i = mine
i2, ok := i.(MyInt)
if !ok {
log.Fatalf("unexpected type for %v", i)
}
fmt.Println(i2)
}
20
Type switch to check type and do appropriate action i is shadowing here, one of few examples where shadowing is idiomatic
func doThings(i interface{}) {
switch i := i.(type) {
case nil:
fmt.Println(i, "is of type interface{}")
case int:
fmt.Println(i, "is of type int")
case MyInt:
fmt.Println(i, "is of type MyInt")
case string:
fmt.Println(i, "is of type string")
default:
fmt.Println("I don't know what type this value is:", j)
}
}
func main() {
var j MyInt = 10
doThings(j)
}
Example in the standard library using type assertion from the standard librar
// copyBuffer is the actual implementation of Copy and CopyBuffer.
// if buf is nil, one is allocated.
func copyBuffer(dst Writer, src Reader, buf []byte) (written int64, err error) {
// If the reader has a WriteTo method, use it to do the copy.
// Avoids an allocation and a copy.
if wt, ok := src.(WriterTo); ok {
return wt.WriteTo(dst)
}
// Similarly, if the writer has a ReadFrom method, use it to do the copy.
if rt, ok := dst.(ReaderFrom); ok {
return rt.ReadFrom(src)
}
// function continues...
}
Example of using fallback code when implementing a newer version of an API This comes from database/sql/driver in the standard library
func ctxDriverStmtExec(ctx context.Context, si driver.Stmt,
nvdargs []driver.NamedValue) (driver.Result, error) {
if siCtx, is := si.(driver.StmtExecContext); is {
return siCtx.ExecContext(ctx, nvdargs)
}
// fallback code is here
}
---