Interface Type Detection: Type assertions
The interface instance stores the type instances that implement the interface. There are two types of instances: Value Type instances and pointer type instances. During the program running, the instance type stored in the interface instance may change dynamically. For example:
// INS is an interface instance var ins shaper // ins storage value type instance ins = C1 // after a period of time ...... // ins stores pointer-type instances. The storage type changes to INS = c2 // some time later... // INS may store another type of instance ins = S1
Therefore, a test interface instance is required to store the value type or pointer type.
The probe method is as follows:ins.(Type)Andins.(*Type). They have two return values. The second return value is the OK return value and boolean type. The first return value is the detected type. There can also be only one returned value: the type detected.
// If the INS stores the type of the value type, the output is if T, OK: = ins. (type); OK {FMT. printf ("% t \ n", v)} // If the INS stores * type of the pointer type, the output is if T, OK: = ins. (* type); OK {FMT. printf ("% t \ n", v)} // test T: = ins for a returned value. (type) T: = ins. (* type)
The following is an example:
Package mainimport "FMT" // shaper interface type shaper interface {area () float64} // square struct type square struct {length float64} // method of Square type implementation area () func (s square) area () float64 {return S. length * s. length} func main () {var ins1, ins2, shaper // instance S1: = new (square) s1.length = 3.0 ins1 = S1 if V, OK: = ins1. (* Square); OK {FMT. printf ("ins1: % t \ n", v)} // Value Type instance S2: = square {4.0} ins2 = S2 if V, OK: = ins2. (square); OK {FMT. printf ("ins2: % t \ n", v )}}
Both of the above printf outputs, because both of them return true for type determination. Ifins2.(Square)Changeins2.(*Square)The second printf will not be output because ins2 stores value-type instances.
Note that,INS must be clear as interface instances. For example, the first two statements below are valid, and the third type is incorrect, because they may be interface instances or copies of Type instances.
VaR ins shaper // correct INS: = shaper (S1) // correct INS: = S1 // Error
When the INS cannot be determined to be an interface instance, use it for testing, suchins.(Square)An error will be reported:
invalid type assertion:ins.(Square) (non-interface type (type of ins) on left)
It indicates that the INS on the left are non-interface types ).
Type Switch Structure
The switch flow control structure can also be used to detect the types of interface instances.This structure is called type-switch..
The usage is as follows:
switch v := ins.(type) {case *Square: fmt.Printf("Type Square %T\n", v)case *Circle: fmt.Printf("Type Circle %T\n", v)case nil: fmt.Println("nil value: nothing to check?")default: fmt.Printf("Unexpected type %T", v)}
Whereins.(type)The lower-case type is a fixed word.
The following is an example:
Package mainimport ("FMT") // shaper interface type shaper interface {area () float64} // circle struct type circle struct {radius float64} // Method Area () func (C * circle) area () in shaper Implementation of Circle Type () float64 {return 3.14 * C. radius * C. radius} // square struct type square struct {length float64} // method of Square type implementation area () func (s square) area () float64 {return S. length * s. length} func main () {S1: = & square {3.3} whichtype (S1) S2: = square {3.4} whichtype (S2) C1: = new (circle) c1.radius = 2.3 whichtype (C1)} func whichtype (N shaper) {Switch V: = n. (type) {Case * Square: FMT. printf ("type square % t \ n", v) Case square: FMT. printf ("type square % t \ n", v) Case * circle: FMT. printf ("type circle % t \ n", v) Case nil: FMT. println ("nil value: Nothing to check? ") Default: FMT. printf (" unexpected type % t ", v )}}
In the above Type-switchcase CircleThe reason is that circle only implements pointer type referers. According to the Implementation Rules of method set on the interface, only the circle example of pointer type can be regarded as interface shaper.case CircleType-switch is incorrect.
Go basic series: interface type detection and type-Switch