I am working with a JSON API to pull forex quotes.
I am unmarshaling to a struct
like so:
type Quote struct {
Symbol string
Bid float32
Ask float32
Price float32
Timestamp int
}
Using a function
like so:
func GetQuotes(symbols []string, api_key string) []Quote {
result := fetch("quotes?pairs=" + strings.Join(symbols, ","), api_key)
quotes := []Quote{}
e := json.Unmarshal(result, "es)
if e != nil {
log.Fatal(e)
}
return quotes
}
My issue is: If I get back an error such as "The data you've requested is not available", how do I properly return the correct type from GetQuotes
?
If I unmarshal using json.RawMessage
I can use a switch to chose the proper struct, such as Quote
or ErrorMessage
, however, then I cannot set a proper return type from GetQuotes
I suggest you to follow the Go way, and return both error and Quotes, here is an example:
func GetQuotes(symbols []string, api_key string) ([]Quote, error) {
quotes := []Quote{}
// A better would be if the fetch
// fuction also returns both
// result and error
result := fetch("quotes?pairs=" + strings.Join(symbols, ","), api_key)
e := json.Unmarshal(result, "es)
if e != nil {
return quotes, e
}
return quotes, nil
}
Now you can check if request or marshaling returns an error.
quotes, err := GetQuotes(symbols, apiKey)
if err != nil {
// handle errors here
}
You can also return the ErrorMessage
type your custom struct instead of error
.
In order to returns different types, you must use an interface in the return statement, here is an example:
package main
import (
"fmt"
)
type Foo struct {}
type Bar struct {}
func Baz(w string) interface{} {
if w == "Foo" {
return Foo{}
}
return Bar{}
}
func main() {
fmt.Printf("%T", Baz("Bar"))
}
=> main.Bar
The Baz
function able to returns both Foo
and Bar
structs.