zsh's return builtin can only return a 32bit signed integer like the _exit() system call. While that's better than most other Bourne-like shells, that still can't return arbitrary strings or list of strings like the rc/es shells. The return status is more about returning a success/failure indication.
Here, alternatively, you can have the function take the name of the array to fill in as argument, like:
myfunc() {
local arrayname=$1; shift
# ...
eval $arrayname'=("$elements[@]")'
# the returned $? will be 0 here for success unless that eval command
# fails.
}
myfunc myarray other args
Your printf '%s\0' approach wouldn't work for array elements that contain NULs.
Instead you could use the qq parameter expansion flag to quote elements on output, and the z (to parse quotes) and Q (to remove quoting) on input like:
myfunc() {
# ...
print -r -- ${(qq)elements}
}
myarray=("${(@Q)${(z)$(myfunc)}}")
But in addition to being less legible, it's also less efficient as it means forking a process and transfering the output of myfunc through a pipe in addition to the quoting/unquoting.
mpv() command mpv --sub-auto=fuzzy --fs --input-ipc-server "$mpv_ipc" "${(0@)$(rpargs "$@")}"