Indeed, for me its usually either slices or writer
It’s an interesting question whether any stdlib container is suitable to be passed across API boundaries, or whether slices are always enough…
How would you deal with containers that don’t translate to slices, like hash maps?
Why should a library user be interested in such implementation details? E.g. if you want the library user to add key/value pairs, add a library API function add_item(key: KeyType, value: ValueType) and to lookup items, add a function get_item(key: KeyType) ?ValueType.
Internally, use a hash map to manage those items, but don’t expose that detail to the user. That way you can later switch to a different hash map implementation without breaking any code which depends on your library.
One case that comes to mind is passing a “dict” to a JSON encoder. I think I’d rather pass (and construct) these types of objects using some standard library HashMap container instead of having libraries craft an API for this type of data.
But the original idea of using slices or a writer instead of an ArrayList seems like a good convention.
Ideally the standard libary would define some sort of abstract interface types (like ‘Dictionary’ or ‘KeyValuePairContainer’) which could be used in the API of user libraries, so that the caller can plug any sort of HashMap under that interface.
It’s the same problem I had in C++, e.g. why does that API want a std::vector when I have my data in a std::array… you’d then end up creating a temporary std::vector just to get your data items into the API (ok in that example a simple slice would serve as that interface).