The Go language implements static strict typing. This means that the type of each variable is known at compile time, and the compiler does not allow operations with incompatible types.
There are two types of type conversion:
Example of explicit conversion:
var i int = 42 var f float64 = float64(i)
Example of type assertion:
var i interface{} = "hello" s, ok := i.(string) if ok { fmt.Println("String value:", s) } else { fmt.Println("i is not a string") }
Conversion is only possible between compatible base types (int → float64, rune → int32, but string → int — is not possible).
Can interface{} hold a nil value, and how can you correctly check if a variable of interface type is indeed nil?
A common trap is comparing an interface holding a nil value directly with nil:
var err error = nil var i interface{} = err fmt.Println(i == nil) // Expected true, but will be false!
The correct way:
Check that both the interface itself is nil and the underlying value is nil:
if i == nil || reflect.ValueOf(i).IsNil() { fmt.Println("i is indeed nil") }
Story
In a backend project, the developer tried to handle various errors through interface{}, comparing them with nil. As a result, the error could not be correctly detected — hidden bugs and incorrect error return logic occurred.
Story
Migration between float64 and int without explicit cast caused silent data loss: values were rounded or cast incorrectly, as the Go compiler requires explicit conversion for such operations.
Story
In deserialization of interface values when working with map[string]interface{} (for example, from JSON), unexpected types of numbers (float64) led to panic when using type assertion without additional check of ok — the service crashed due to runtime error.