How to parse slice inside json in golang? [closed] - go

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Closed 5 years ago.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Improve this question
I am trying to unmarshal json data. The slice inside is deliberately without quotes, because this is what I am getting from https (added manually \ before ")
data:="{\"queryEndTime\" : \"2017-11-15T14:39:00Z\", \"message\" : [{\"spamScore\":67,\"phishScore\":0}]}"
into Message struct:
type Message struct {
QueryEndTime string `json:"queryEndTime"`
Message []string `json:"message"`
}
but I am getting correct QueryEndTime and empty Message. I tried to change Message type but it always stays empty
var message Message
json.Unmarshal([]byte(data), &message)
fmt.Printf("QueryEndTime: %s\nMessage: %s\n", message.QueryEndTime, message.Message)
QueryEndTime: 2017-11-15T14:39:00Z
Message: []
See it in go playground https://play.golang.org/p/on0_cSKb0c.

package main
import (
"encoding/json"
"fmt"
)
type Message struct {
QueryEndTime string `json:"queryEndTime"`
// you need to use a struct can use anon struct
Message []struct {
SpamScore int `json:"spamScore"`
PhishScore int `json:"phishScore"`
} `json:"message"`
}
func main() {
var message Message
// You can use backticks to for your example JSON, so that you don't have to escape anything.
data := `{
"queryEndTime" : "2017-11-15T14:39:00Z",
"message" : [
{"spamScore":67, "phishScore":0}
]
}`
// please check for errors
err := json.Unmarshal([]byte(data), &message)
if err != nil {
fmt.Println(err)
}
// +v prints structs very nicely
fmt.Printf("%+v\n", message)
}
https://play.golang.org/p/Mu3WZCej3L
Have fun!

Related

How to parse map[string]interface{} [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 1 year ago.
Improve this question
I am unable to parse json that has string keys and array as value ending up with json: Unmarshal(non-pointer map[string]interface {}) error.
package main
import (
"encoding/json"
"fmt"
)
func main() {
var s map[string]interface{}
err := json.Unmarshal([]byte("{\"a\":[1,2,3]}"), s)
if err != nil {
panic(err)
}
fmt.Println("Nice parse!")
}
https://go.dev/play/p/AXlF8I-f9-p
Unmarshal parses the JSON-encoded data and stores the result in the value pointed to by v. If v is nil or not a pointer, Unmarshal returns an InvalidUnmarshalError. Add &s as a parameter
err := json.Unmarshal([]byte("{\"a\":[1,2,3]}"), &s)

Golang concatenate two slices of pointers [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 1 year ago.
Improve this question
In my GoLang program which invokes a REST API, i need to collect the responses from different REST API's which return slices of pointers of the same struct.
I am attempting to concatenate the slices of pointers using append and i am getting error similar to what is shown below.
I think append does not support such an operation , is there any alternative to this ?
cannot use response (type []*string) as type *string in append
A go playground link for the problem ,i am trying to demonstrate is given here.
https://play.golang.org/p/lnzSd2kbht0
package main
import (
"fmt"
)
func main() {
var fruits []*string
response := GetStrings("Apple")
fruits = append(fruits, response...)
response = GetStrings("Banana")
fruits = append(fruits, response...)
response = GetStrings("Orange")
fruits = append(fruits, response...)
if fruits == nil || len(fruits) == 0 {
fmt.Printf("Nil Slice")
} else {
fmt.Printf("Non nil")
fmt.Printf("%v", fruits)
}
}
func GetStrings(input string) []*string {
var myslice []*string
myslice = append(myslice, &input)
return myslice
}
I cannot change the REST API or the function signature to return the slice of structs itself.
To append all elements of a slice to another slice, use:
resultSlice=append(slice1, slice2...)

Why I got an empty struct after json.Unmarshal()? [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 2 years ago.
Improve this question
coders. I'm completely newbie to Go and got a little bit confused about json.Unmarshal output:
package main
import (
"encoding/json"
"fmt"
)
func main() {
s := `[{"First":"James","Last":"Bond","Age":32,"Sayings":["Shaken, not stirred","Youth is no guarantee of innovation","In his majesty's royal service"]},{"First":"Miss","Last":"Moneypenny","Age":27,"Sayings":["James, it is soo good to see you","Would you like me to take care of that for you, James?","I would really prefer to be a secret agent myself."]},{"First":"M","Last":"Hmmmm","Age":54,"Sayings":["Oh, James. You didn't.","Dear God, what has James done now?","Can someone please tell me where James Bond is?"]}]`
var res []struct{}
err := json.Unmarshal([]byte(s), &res)
if err != nil {
fmt.Println(err)
}
fmt.Println(res)
}
Output:
[{} {} {}]
Why is it empty?
You can try it here: https://play.golang.org/p/yztOLJADIXx
If you want to unmarshal JSON objects without knowing their fields, use a map[string]interface{}:
package main
import (
"encoding/json"
"fmt"
)
func main() {
s := `[{"First":"James","Last":"Bond","Age":32,"Sayings":["Shaken, not stirred","Youth is no guarantee of innovation","In his majesty's royal service"]},{"First":"Miss","Last":"Moneypenny","Age":27,"Sayings":["James, it is soo good to see you","Would you like me to take care of that for you, James?","I would really prefer to be a secret agent myself."]},{"First":"M","Last":"Hmmmm","Age":54,"Sayings":["Oh, James. You didn't.","Dear God, what has James done now?","Can someone please tell me where James Bond is?"]}]`
var res []map[string]interface{}
err := json.Unmarshal([]byte(s), &res)
if err != nil {
fmt.Println(err)
}
fmt.Println(res)
}
Try it here: https://play.golang.org/p/iPlBgguE8Kk
However, if you know the names of the fields you're going to unmarshal, you should define the structure. In your case it would look like that:
type Person struct {
First string `json:"First"`
Last string `json:"Last"`
Age int `json:"Age"`
Sayings []string `json:"Sayings"`
}
Try this solution here: https://play.golang.org/p/jCrCteYTaIf

Why are errors nillable in Go? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
An error in Go can be nil. The following compiles:
var err error
err = nil
err = errors.New("hello")
Yet errors are values, and value types are not nullable in Go.
Looking at error, it is an ordinary interface:
type error interface {
Error() string
}
implemented by this struct:
type errorString struct {
s string
}
No pointers here. There is a method that takes a pointer receiver,
func (e *errorString) Error() string {
return e.s
}
Yet that doesn't explain why error behaves as a pointer rather than a value.
errors.New() does return a pointer,
func New(text string) error {
return &errorString{text}
}
which makes my third code line above more puzzling -- we are assigning the result of New to a value variable.
How does this work?
I think you may be conflating some concepts. Yes, "errors are values", in that they are not exceptions that can be thrown, but rather they are just regular values returned from a function like any other return value. The Go quality "errors are values" has nothing to do with value vs reference semantics.
The built-in type error is an interface, and all interface values are nilable, so error is nilable.

Protobuf/Go cannot use literal * (type *) as type * in array or slice literal [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 2 years ago.
Improve this question
I have a struct in my generated proto file that looks like this (simplified):
type Record struct {
Field1 int64 `protobuf:"varint,1,opt,name=field1,proto3" json:"field1,omitempty"`
Field2 []byte `protobuf:"bytes,2,opt,name=field2,proto3" json:"field2,omitempty"`
}
and I'm trying to call it in my Go file
func foo(c messagepb.MessageServiceClient){
fmt.Println("Starting to send message...")
msgs := []*messagepb.MessageRequest{
recordpb.Record{ //error msg here
Field1: 1,
Field2: []byte{byte('a')},
}
}
...
}
but I get this error at the recordpb.Record line:
cannot use recordpb.Record literal (type recordpb.Record) as type *messagepb.MessageRequest in array or slice literal
If it helps, here's my messagepb:
message.proto
message MessageRequest { recordpb.Record records = 1; }
message.pb.go
type MessageRequest struct {
Record *recordpb.Record `protobuf:"bytes,1,opt,name=record,proto3" json:"record,omitempty"`
}
I can't find anything useful about why this is happening... Any ideas?
Looks like you are creating a slice of []*messagepb.MessageRequest and then adding a recordpb.Record to it. recordpb.Record is not the same type as *messagepb.MessageRequest.
Given this type
type MessageRequest struct {
Record *recordpb.Record `protobuf:"bytes,1,opt,name=record,proto3" json:"record,omitempty"`
}
It looks like your msgs var should be
msgs := []*messagepb.MessageRequest{
{
Record: &recordpb.Record{
Field1: 1,
Field2: []byte{byte('a')},
},
},
}
#mkopriva 's comments above add some nice explanation to this.

Resources