I have a question of etiquette. I'm implementing an RPC server, which is why this function takes a value and uses an out-variable in its parameter. This function reads from a container/list
and fills a normal array buffer for return through the out-variable.
func (t *PersonalPlaylist) GetPlaylist(n int, reply *[]string) error {
t.listMutex.Lock()
bufLen := min(n, t.list.Len()) // mark
buf := make([]string, bufLen) // mark
e := t.list.Front()
for i := 0; i < n; i++ {
s := e.Value.(string)
buf[i] = fmt.Sprintf("String #%d: %s", i, s)
e = e.Next()
if e == nil {
break
}
}
*reply = buf
t.listMutex.Unlock()
return nil
}
[Note that this function should limit the maximum buffer size.]
Of particular note are the marked lines. I'm trying to decide whether the buffer should always be of the requested size (n) and be zero/nil-filled beyond the real data, or if the buffer should sometimes be shorter than the request value.
If the buffer is always the requested size, the code calling this function can use the value it passed as a parameter as part of the loop through the array. However, some of the values in the array may be nil, so it would have to nil check in each loop:
for i := 0; i < n; i++ {
if reply[i] == nil {
break; // or continue
}
}
In the alternate scenario, the caller can't be sure of the buffer size, and will have to call len(reply)
instead, but can be largely guaranteed that all the values will be non-nil.
I'm leaning towards using the function as is, and making callers unsure of the length of the buffer (while still guaranteeing a maximum possible buffer size); this is primarily because this is a relatively high level interface that will only get higher as I continue development. Is there a convention I'm not aware of that this code breaks? Or some etiquette that pushes this one way or another?