packagemainimport"fmt"vari=5varstr="ABC"typePersonstruct{namestringageint}typeAnyinterface{}funcmain(){varvalAnyval=5fmt.Printf("val has the value: %v\n",val)val=strfmt.Printf("val has the value: %v\n",val)pers1:=new(Person)pers1.name="Rob Pike"pers1.age=55val=pers1fmt.Printf("val has the value: %v\n",val)switcht:=val.(type){caseint:fmt.Printf("Type int %T\n",t)casestring:fmt.Printf("Type string %T\n",t)casebool:fmt.Printf("Type boolean %T\n",t)case*Person:fmt.Printf("Type pointer to Person %T\n",t)default:fmt.Printf("Unexpected type %T",t)}}
输出:
在上面的例子中,接口变量 val 被依次赋予一个 int,string 和 Person 实例的值,然后使用 type-switch 来测试它的实际类型。每个 interface {} 变量在内存中占据两个字长:一个用来存储它包含的类型,另一个用来存储它包含的数据或者指向数据的指针。
val has the value: 5
val has the value: ABC
val has the value: &{Rob Pike 55}
Type pointer to Person *main.Person
package main
import "fmt"
type specialString string
var whatIsThis specialString = "hello"
func TypeSwitch() {
testFunc := func(any interface{}) {
switch v := any.(type) {
case bool:
fmt.Printf("any %v is a bool type", v)
case int:
fmt.Printf("any %v is an int type", v)
case float32:
fmt.Printf("any %v is a float32 type", v)
case string:
fmt.Printf("any %v is a string type", v)
case specialString:
fmt.Printf("any %v is a special String!", v)
default:
fmt.Println("unknown type!")
}
}
testFunc(whatIsThis)
}
func main() {
TypeSwitch()
}
any hello is a special String!
type Vector struct {
a []Element
}
func (p *Vector) At(i int) Element {
return p.a[i]
}
func (p *Vector) Set(i int, e Element) {
p.a[i] = e
}
var dataSlice []myType = FuncReturnSlice()
var interfaceSlice []interface{} = dataSlice
var dataSlice []myType = FuncReturnSlice()
var interfaceSlice []interface{} = make([]interface{}, len(dataSlice))
for i, d := range dataSlice {
interfaceSlice[i] = d
}
package main
import "fmt"
type Node struct {
le *Node
data interface{}
ri *Node
}
func NewNode(left, right *Node) *Node {
return &Node{left, nil, right}
}
func (n *Node) SetData(data interface{}) {
n.data = data
}
func main() {
root := NewNode(nil, nil)
root.SetData("root node")
// make child (leaf) nodes:
a := NewNode(nil, nil)
a.SetData("left node")
b := NewNode(nil, nil)
b.SetData("right node")
root.le = a
root.ri = b
fmt.Printf("%v\n", root) // Output: &{0x125275f0 root node 0x125275e0}
}
var ai AbsInterface // declares method Abs()
type SqrInterface interface {
Sqr() float
}
var si SqrInterface
pp := new(Point) // say *Point implements Abs, Sqr
var empty interface{}
empty = pp // everything satisfies empty
ai = empty.(AbsInterface) // underlying value pp implements Abs()
// (runtime failure otherwise)
si = ai.(SqrInterface) // *Point has Sqr() even though AbsInterface doesn’t
empty = si // *Point implements empty set
// Note: statically checkable so type assertion not necessary.
type myPrintInterface interface {
print()
}
func f3(x myInterface) {
x.(myPrintInterface).print() // type assertion to myPrintInterface
}