0

I'm fresh in Golang. I want to assign the return value of a multiple return value function, to a list(or any container). Consider the below function:

func Split32(in uint32) (b0, b1, b2, b3 byte) {
b0 = byte(in & 0xFF)
b1 = byte((in & uint32(0xFF<<8)) >> 8)
b2 = byte((in & uint32(0xFF<<16)) >> 16)
b3 = byte((in & uint32(0xFF<<24)) >> 24)
return
}

I know below calling notation:

var a uint32 = 0xABFEAA12
c0, c1, c2, c3 := bytes.Split32(a)

And it is working fine for me. But I want to know is there any possibility to assign this return value directly to a list(or another container):

var a uint32 = 0xABFEAA12
l := bytes.Split32(a)
SpongeBob
  • 383
  • 3
  • 16
  • What list do you want to assign to? A slice (e.g. `[]byte`)? – icza Oct 30 '20 at 12:55
  • @icza everything that possible; list, slice, or ... . I wanna a collection/container that be able to iterate over that. – SpongeBob Oct 30 '20 at 12:59
  • Suppose your function were to have the following signature: `func Split32(in uint32) (b0 byte, i32 int32, s string, ui64 uint64)`; how would you expect the compiler to handle `dst := bytes.Split32(...)`? – kostix Oct 30 '20 at 13:05

1 Answers1

2

You may use a variadic helper function that accepts any number of arguments. The variadic parameter is treated as a slice inside the function (it is a slice), so you can use it / return it.

This helper is one of the simplest function you can ever write:

func pack(data ...byte) []byte {
    return data
}

Testing it:

func one() byte                 { return 1 }
func two() (byte, byte)         { return 1, 2 }
func three() (byte, byte, byte) { return 1, 2, 3 }

func main() {
    var data []byte

    data = pack(one())
    fmt.Println(data)

    data = pack(two())
    fmt.Println(data)

    data = pack(three())
    fmt.Println(data)
}

Output (try it on the Go Playground):

[1]
[1 2]
[1 2 3]

Note that the above pack() function can only be used with functions that return bytes and nothing more. If the functions you want to use it with have other return types too, you may change the type from byte to interface{}:

func pack(data ...interface{}) []interface{} {
    return data
}

Testing it with these functions:

func one() (byte, int)                 { return 1, 2 }
func two() (byte, string, interface{}) { return 1, "b", "c" }
func three() (string, byte, error)     { return "x", 2, io.EOF }

(and of course using var data []interface{})

The output is (try it on the Go Playground):

[1 2]
[1 b c]
[x 2 EOF]

See related question: how to parse multiple returns in golang

icza
  • 389,944
  • 63
  • 907
  • 827