Go Type Assertion: Difference between revisions

From NovaOrdis Knowledge Base
Jump to navigation Jump to search
m (Ovidiu moved page Go Type Assertions to Go Type Assertion without leaving a redirect)
 
(6 intermediate revisions by the same user not shown)
Line 4: Line 4:
* [[Go_Language#Type_Assertions|Go Language]]
* [[Go_Language#Type_Assertions|Go Language]]
* [[Go Interfaces#Type_Assertions|Go Interfaces]]
* [[Go Interfaces#Type_Assertions|Go Interfaces]]
* [[Go Type Switch#Overview|Type Switch]]


=Overview=
=Overview=
An interface hides the differences between the types implementing it and emphasizes the commonality. However, there are times you may want to know what exact concrete type exists behind the interface. Type assertions can be used for type disambiguation.
A type assertion is an expression that probes whether an interface is of a certain concrete type, and if it is, returns a variable of that type (see [[Go_Interfaces#Interface_Values|here]] for the code used in the example).
A type assertion is an expression that probes whether an interface is of a certain concrete type, and if it is, returns a variable of that type (see [[Go_Interfaces#Interface_Values|here]] for the code used in the example).
<syntaxhighlight lang='go'>
<syntaxhighlight lang='go'>
var i SomeInterface
var i SomeInterface = &SomeImplementation{"test"}


v, ok := i.(*SomeImplementation)
v, ok := i.(*SomeImplementation)
</syntaxhighlight>
</syntaxhighlight>


An interface hides the differences between the types implementing it and emphasizes the commonality. However, there are times you may want to know what exact concrete type exists behind the interface. Type assertions can be used for type disambiguation.
The type assertion also works when the interface variable only carries a [[Go Interfaces#Dynamic_Type|dynamic type]], but not a [[Go Interfaces#Dynamic_Value|dynamic value]]:
 
<font color=darkkhaki>Actually, it worked with:
<syntaxhighlight lang='go'>
v, isTypeName := i.(*TypeName)
</syntaxhighlight>
Why is that? Probably because the interface variable contained a pointer to the actual type.
</font>
 
Usage example:
<syntaxhighlight lang='go'>
type SomeInterface interface {
  MethodA()
}
 
type TypeA struct {
  s string
}
 
func (v *TypeA) MethodA() {
  fmt.Println("TypeA.MethodA()")
}
 
type TypeB struct {
  s string
}
 
func (v *TypeB) MethodA() {
  fmt.Println("TypeB.MethodA()")
}
 
...
 
var i SomeInterface
i = &TypeA{"A"}
b := &TypeB{"B"}
 
a, isTypeA := i.(*TypeA)
fmt.Printf("%v, %t\n", a, isTypeA) // will print {A}, true
b, isTypeB := i.(*TypeB)
fmt.Printf("%v, %t\n", b, isTypeB) // will print <nil>, false
</syntaxhighlight>
 
=Type Assertion=
=Type Switch=
A type switch is a new [[Go_Language#Type_Switch|control structure]] introduced by Go.
 
Type assertion with <code>switch</code>:
<syntaxhighlight lang='go'>
<syntaxhighlight lang='go'>
var i SomeInterface
var i SomeInterface
i = TypeA{"A"}
var t *SomeImplementation
i = t


switch v := i.(type) {
v, ok := i.(*SomeImplementation) // ok is true, v is nil, as there is no dynamic value
  case TypeA:
fmt.Printf("TypeA: %v\n", v)
  case TypeB:
fmt.Printf("TypeB: %v\n", v)
}
</syntaxhighlight>
</syntaxhighlight>

Latest revision as of 16:32, 14 August 2024

External

Internal

Overview

An interface hides the differences between the types implementing it and emphasizes the commonality. However, there are times you may want to know what exact concrete type exists behind the interface. Type assertions can be used for type disambiguation.

A type assertion is an expression that probes whether an interface is of a certain concrete type, and if it is, returns a variable of that type (see here for the code used in the example).

var i SomeInterface = &SomeImplementation{"test"}

v, ok := i.(*SomeImplementation)

The type assertion also works when the interface variable only carries a dynamic type, but not a dynamic value:

var i SomeInterface
var t *SomeImplementation
i = t

v, ok := i.(*SomeImplementation) // ok is true, v is nil, as there is no dynamic value