1

I have custom types Int64Array, Channel and ChannelList like:

type Int64Array []int64

func (ia *Int64Array) Scan(src interface{}) error {
  rawArray := string(src.([]byte))
  if rawArray == "{}" {
    *ia = []int64{}
  } else {
    matches := pgArrayPat.FindStringSubmatch(rawArray)
    if len(matches) > 1 {
      for _, item := range strings.Split(matches[1], ",") {
        i, _ := strconv.ParseInt(item, 10, 64)
        *ia = append(*ia, i)
      }
    }
  }
  return nil
}

func (ia Int64Array) Value() (driver.Value, error) {
  var items []string
  for _, item := range ia {
    items = append(items, strconv.FormatInt(int64(item), 10))
  }
  return fmt.Sprintf("{%s}", strings.Join(items, ",")), nil
}

type Channel int64

type ChannelList []Channel

How can I embed Int64Array to ChannelList such that I can call Scan and Value methods on it? I tried the following:

type ChannelList []Channel {
    Int64Array
}

but I'm getting syntax error. What's important is to make sure ChannelList items are of type Channel, if this isn't possible via embedding I might just create stand-alone functions to be called by both ChannelList and Int64Array.

Marconi
  • 3,601
  • 4
  • 46
  • 72

1 Answers1

3

An anonymous (or embedded field) is found in a struct (see struct type), not in a type alias (or "type declaration").

You cannot embed a type declaration within another type declaration.

Plus, as illustrated by the answers to "Go: using a pointer to array", you shouldn't be using pointers to slice, use directly the slice themselves (passed by value).

Wessie kindly points out in the comments that (ia *Int64Array) Scan() uses pointer to a slice in order to mutate the underlying array referenced by said slice.
I would prefer returning another slice instead of mutating the existing one.
That being said, the Golang Code Review does mention:

If the receiver is a struct, array or slice and any of its elements is a pointer to something that might be mutating, prefer a pointer receiver, as it will make the intention more clear to the reader.

Community
  • 1
  • 1
VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
  • `Value` already passes normally, `Scan` requires a pointer because it **mutates** the slice with `append`. Your last paragraph is wrong, and it seems it has become a habit to just always include it when you see a pointer to a slice. – Wessie Dec 30 '14 at 12:16
  • @Wessie agreed (answer edited). The name "Scan" has me confused. I didn't expect what would seem to be a read-only operation (`Scan`) to mutate anything on its receiver. – VonC Dec 30 '14 at 12:46