扫描仪可以有切片接收器吗?

The Scanner interface (https://golang.org/pkg/database/sql/#Scanner) makes it quite easy to configure how a type is deserialized by the database/sql API from data that has been read from a database.

I've used this in various ways to handle my own types, but I just tried reading a denormalised string list into a slice of strings, e.g.

type Roles []string

func (rs Roles) Scan(value interface{}) error {
    ...
}

It's normal for the Scan receiver to be a pointer to a zero-valued instance of the type. In the case I'm trying to write, it's a slice instead.

Is this possible?

If so, how is the size of the slice determined (it isn't known until the scanner starts parsing, e.g. by splitting an input string on commas or something similar) ?

Yes, this is possible, but you want to define the method on *Roles instead. Then you can grow the slice as needed.

func (rs *Roles) Scan(value interface{}) error {
    ...  check not nil
    ...  split string into words
    *rs = make(RosterRoles, len(words))
    ...  range across the words
}

The database/sql library will be using this something like

var rs Roles
err := rs.Scan("abc,def")
// rs contains []string{"abc", "def"}

Thanks to @Peter for this answer.