0

I am fetching a JSON array from PostgreSQL, and I would like to read it into a map. I am able to Unmarshal the values into a []string slice, but what I actually want is a map[string]bool.

I've written a custom type for the column with a Scan interface that converts the JSON array into a slice of strings first, then reads each string into the custom map type as keys.

type custMap map[string]bool

func (m *custMap) Scan(src interface{}) error {
  b, ok := src.([]byte)
  if !ok {
    return error(errors.New("Error Scanning Array"))
  }

  s := make([]string, 0)
  json.Unmarshal(b, &s)
  for _, v := range s {
    (*m)[v] = true
  }

  return nil
}


type data struct {
  vals custMap `json: "vals"`
}

The query I am trying to scan returns a row with a column vals which is a JSON array: ["some", "arr", "vals"], where the custom type is used like so:

var d models.data
sqlDB.QueryRow().Scan(&d.vals)

My expected output is a struct with the following shape

{ vals: map[string]bool { "some": true, "arr": true, "vals": true }

This compiles fine, but my code panics with "assignment to entry in nil map"

How can I fix my Scan function? Is it even possible to do this with a map type?

3
  • Please provide line numbers of the source and the error message. I suspect the error happens on the line (*m)[v] = true but that is just my suspicion. Commented Jun 2, 2017 at 7:36
  • Yes! that is where i'm getting 'assignment to entry in nil map' Commented Jun 2, 2017 at 7:50
  • The specific error thrown is 0http: panic serving [::1]:59847: assignment to entry in nil map. I know it's that line because for my first try at this I did not use a pointer there: m[v] = true Which resulted in this compile error: invalid operation: m[v] (type *SCMap does not support indexing) Commented Jun 2, 2017 at 7:51

2 Answers 2

2

You are calling your method Scan of type *custMap on a unitialised map. Initialize d.vals either like

d.vals = custMap{}

or

d.vals = make(custMap)

Other answers already provide an explanation.

Sign up to request clarification or add additional context in comments.

Comments

1

The Go Programming Language Specification

Map types

A map is an unordered group of elements of one type, called the element type, indexed by a set of unique keys of another type, called the key type. The value of an uninitialized map is nil.

A new, empty map value is made using the built-in function make, which takes the map type and an optional capacity hint as arguments:

make(map[string]int)
make(map[string]int, 100)

The initial capacity does not bound its size: maps grow to accommodate the number of items stored in them, with the exception of nil maps. A nil map is equivalent to an empty map except that no elements may be added.

I don't see a make to initialize your map: "A nil map is equivalent to an empty map except that no elements may be added."

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.