I am trying to abstract the following pattern that seems to occur quite a lot, but the only way I can think of doing so is through a generic function:
func DoStuff () MyType {
result, err := SomeProcess() // returns MyType
if err != nil {
log.Fatal(err)
}
return result // or do something else with it
}
Here's my solution:
func FailOnError(value interface{}, err error) interface{} {
if err != nil {
log.Fatal(err)
}
return value
}
func DoStuff () MyType {
return FailOnError(SomeProcess())
}
The problem is that I don't have compile-time type safety, and if I want to do anything further with the result I need to explicitly type cast it, e.g.
type MyType struct {
value int
}
// Assuming a function with this signature
func GetItem() (MyType, error)
func Add () MyType {
item := MyType(FailOnError(GetItem()))
}
This is ok, I guess, but rather inelegant. Also, it means manually enforcing types which is always somewhat fragile and a potential performance hit.
Is there a better, or more idiomatic way of doing this?
Edit: Since this seems to be a hated question, how about I use the following example instead:
func Identity(x interface{}) interface{} {
return x
}
Usage would need to be:
x = int(Identity(1))
y = MyType(Identity(MyType{value}))
And there is nothing stopping me from doing
x = int(Identity(MyType{value}))
Identity
is intentionally trivial, but need not necessarily be so. I could be, for example, and method designed to do some logging, or mutate an object and return it. Another situations I have is where I want to do some work on some types defined in various external libraries - they are similar enough that I can write a single function to handle all of them, but they don't share an interface.