Home > Mobile >  Why can't I use an empty interface that holds a concrete type of string as a return value in a
Why can't I use an empty interface that holds a concrete type of string as a return value in a

Time:02-15

I am a newcomer of go and recently I am following the instruction of A Tour of Go. I am reading the chapter on Interface and I am really confused by the concept.

The code is as follows

package main

import "fmt"

func main() {
    testTypeAssertion()
}

func testTypeAssertion() string {
    var i interface{}="hello"
    fmt.Printf("type of i is %T",i)
    return i
//  return "hello"
}

In this case, it will cause error

# example
./prog.go:12:2: cannot use i (type interface {}) as type string in return argument: need type assertion

But if I comment return i and uncomment return "hello", it goes like this

type of i is string

So why exactly do we need a type assertion here? What's the type of i exactly?

I believe this question is different from cannot use type interface {} as type person in assignment: need type assertion. Because in that question the poster is trying to assign an empty interface value to a variable that has a concrete self-defined type person. In my question, I am trying to figure out why an interface holding a concrete string value cannot be a return value of a function whose return value type is exactly string.

Thanks to mkopriva's answer in the comment section and bugstop's answer. I will accept that it's caused by the different usage of static type and dynamic type. By the way, Reality's answer is very interesting and really helped me to understand the whole concept!

CodePudding user response:

Think of an interface as a little box that holds a type and a value. The box has methods that map to methods on the value in the box.

The statement fmt.Printf("type of i is %T",i) prints the type in the box, not the type of the box itself. Reflect package trickery is required to print the type of i. but that's outside the scope of this question.

The statement return i does not compile because interface{} is not a string. The box contains a string, but the box is not a string.

We can get the value out of the box using a type assertion: return i.(string). This statement panics if i does not contain a string.

CodePudding user response:

it's an interface value i with a dynamic type string.

It may be useful to read about:

CodePudding user response:

The variable i is of type interface{}, and its value is the string "hello". An interface is simply a method-set, and since interface{} has no methods specified, all types satisfy it. Because of this, the assignment i="hello" works.

However, you cannot return an interface{} where a string is required, because string is not the same type as an interface{}. You could have returned a string where an interface{} is required, because a string implements interface{}.

  •  Tags:  
  • go
  • Related