1

I am new to GO language and I am trying to get a value from a function which returns two strings, that is [str1, str2]

 ret, err := fun1(....)

And function's prototype is

func fun1(...) (interface{}, error)

I print ret, it is

[[57 57 56 56] [97 100 98 49 57 55 102 98 49 101 57 48 52 98 102 56 55 102 52 56 57 57 55 54 49 55 101 57 49 100 98 49]]

which looks like the type [][]uint8, so, I tried this way

    v, _ := ret.([][]uint8)
    str1, _ := strconv.Atoi(string(v[0]))
    str2, _ := strconv.Atoi(string(v[1]))

it failed, v is []

And I also tried:

   v, _ := ret.([]string)

nothing changed

How to solve this? Any help will be appreciated :)

PS: I debug and find the first string is "9988"

8
  • 1
    Do not disregard errors by assigning them to underscores. Check them and print them. They will most probably provide you a solution. Commented Nov 25, 2015 at 14:07
  • 1
    Does v := ret.([]string) panic? If yes, what does the panic message say? Commented Nov 25, 2015 at 14:07
  • 1
    go types are not covariant. You need to iterate through the [][]byte and convert each slice to a string. Commented Nov 25, 2015 at 14:17
  • 2
    Read the Go FAQ: golang.org/doc/faq. Do the Tour of Go: tour.golang.org/welcome/1. Do not use interface {}. Really. Don't. Commented Nov 25, 2015 at 14:29
  • 1
    it is a API, not mine... @Volker Commented Nov 25, 2015 at 14:38

2 Answers 2

4

The value ret is an []interface{} containing []byte elements. Use the following code to convert to a slice of strings:

// Use type assertion to get []interface from ret
sitf, ok := ret.([]interface{})
if !ok { /* handle unexpected type here */ }

// Create the result slice.
s := make([]string, len(sitf))

// For each element …
for i := range sitf {
    // Use type assertion to get []byte from interface{}
    sbyte, ok := sitf[i].([]byte)
    if !ok { /* handle unexpected type here */ }

    // Convert the []byte to a string and set in result
    s[i] = string(sbyte)
}

I know from your other questions that you are asking about Redigo. You can use the redis.Strings helper function instead of the code above:

s, err := redis.Strings(fun1(....))

The variabile s is a []string.

See the documentation about reply helpers for more information.

Sign up to request clarification or add additional context in comments.

2 Comments

well that would have been helpful information in the question.
It really helps, that's just what @JimB says, ref: github.com/garyburd/redigo/blob/master/redis/reply.go#L250
0

You have a slice of slices, you need to cast each slice into what you want. Let's say they're bytes and you want to print each string in the slice, then:

ret, err := fun1(....)
if err != nil {
     panic(err)
}
for idx, val := range ret.([][]byte) {
     fmt.Println("At idx", idx, "string:", string(val))
}

Example with the data above: https://play.golang.org/p/VsZhSaGmQk

2 Comments

I got a panic here: interface conversion: interface is []interface {}, not [][]uint8
Why is your function that is supposed to be returning two strings (as you said) not returning two strings in the first place? Surely that's a better place to start.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.