Hi Nquyen,
I don't fully understand the Go typesystem, but I have used strings a bit FlatBuffers Go.
I believe the reason is that you can easily convert a byte array to a string in Go, but a string cannot be nil, while a byte array can.
Because FlatBuffers has potentially many missing or default fields, you often need to test of the string was absent.
This doesn't answer all your questions, but it explains why a string looks like a byte array.
Why byte arrays do not have the same byte array interface also puzzled me initially. But it likely has something to do with endian translation. In your case a byte array, like strings, will never have endian issues, but if you had a vector of shorts, you would need conversion. I think the Go Api ought to have an extra accessor method for byte arrays similar to strings.
In the flatcc interface for C (which I wrote), there are similar array get methods, but you can also the vector type as a C array directly, which is only safe for byte arrays, or when you know you are on little endian platforms.