With the following code:
var i interface{} = "hello"
f, ok := i.(float64)
fmt.Println(f, ok)
f = i.(float64) // panic
fmt.Println(f)
Why is not catching error will cause panic but catching error will not cause a panic? Any documentation or blogpost explaining this concept?
This is a type assertion & is documented in the Go spec here:
The value of ok is true if the assertion holds. Otherwise it is false and the value of v is the zero value for type T. No run-time panic occurs in this case.
With the check in place & there is a type mismatch, the value will be set to the "zero" value of type float32 (a number) so 0.
Without the runtime check, you should be absolutely sure the type will match, and the spec dictates a panic will occur if not.
This pattern is no different than basic error checking e.g.
// v, err := someapi(). // Should check err ...
v, _ := someapi() // deliberately ignore error
v.SomeMethod() // ... Panic as v probably nil if there was an error