Home  >  Article  >  Backend Development  >  What's the reasoning behind Go's "type assertion" approach?

What's the reasoning behind Go's "type assertion" approach?

王林
王林forward
2024-02-06 08:12:07893browse

Go 的“类型断言”方式背后的原因是什么?

Question content

I am trying to understand the fact that golang's type assertion only applies to variables explicitly defined as interface types, not to concrete type (i.e. "string", "int32"), etc...).

Here is a quick and simple code example that illustrates the root cause of my confusion:

package main

import "fmt"

// here we define an interface type:
type Shape interface {
    DoubleSize() int32
}

// here we define a new type which is really just an int32:
type Rect int32

// here we make "Rect" type above comply with the "Shape" interface by implementing the methods of that interface
// and so, since the interfaces in Go are implemented implicitly, this should make the "Rect" type an implicit instance of the "Shape" interface
func (theShape Rect) DoubleSize() int32 {
    return int32(theShape) * 2
}

// this function expects its "someShape" parameter to be of "Shape" type (or "the type that quacks like "Shape" interface does))
func whateverFunction(someShape Shape) int32 {
    return someShape.DoubleSize()
}

func main() {
    var newRect = Rect(5)
    // ^^ if this is instead written as "var newRect Shape = Rect(5)" no error with type assertion happens down the line

    whateverFunction(newRect) // the function works just fine because "newRect" implicitly implements the "Shape" interface — the one that this function expects to receive.  

    // !! but type assertion doesn't work on "newRect"
    v, ok := newRect.(Shape) // error: invalid operation: newRect (variable of type Rect) is not an interface
    if !ok {
        fmt.Println("type assertion failed")
        return
    }
    fmt.Println("This is v:", v)
}
As the title of this question suggests, I can't understand the reasoning behind implementing type assertions only for interface types and checking whether the underlying value assigned to a variable that explicitly implements that interface is the value we specified internally".(t )" assertion method. This makes me think "type assertion" is an unintentional misnomer, meaning it applies to all types but not, only to interface types.

I mean, there obviously must be a reason behind this language design decision, and I think it might have something to do with the idiomatic way golang is written, but even though I've seen tons of resources on this issue, they never specify it reason.

The reason it makes sense to me is if a go program should "better (I assume, since explicit interface definition is optional)" written with all variables representing some interface (behavior), so It makes sense to define an explicit interface on variables for the purposes of clarity and readability.

But as I mentioned, I've never seen any resource specifically explaining why the "type assertion" feature is implemented in go, and I hope you can help me clear up this confusion.

-- upd 1 - Adding something to clarify my question:

I think, my core question is about the reason (which I don't understand) that type assertion only works when the variable's interface is implemented explicitly, but not when the interface is implemented implicitly.

As demonstrated by "whateverfunction", the code does consider "newrect" to implement the "shape" interface, or "be an implementation of the "shape" interface" (otherwise the function would not be applicable variable, but it does), but the code behind the type assertion ".(t)" method does not treat "newrect" as an implementation of the "shape" interface.

So, if there are differences in considerations regarding interface implementation in golang, I think there must be a reason (differentiation) behind such design decisions.

That's why I mentioned that the only reason I can think of so far is if this is a way to get people to write go code in some way.


Correct Answer


You can check out Burak Serdar's answer - you may find it more concise and helpful. Still, I'll post the entire chain of reasoning that finally made it "click" for me:

|-> Interfaces are used when we are not sure of the exact type of data we expect to receive (because, for example, the same parameter in a function in a program may receive different types of data as a result of user input ), but we know the exact behavior the data provided should have.

^^ Therefore, the actual type of the value stored in the interface is unknown at compile time. (Otherwise, obviously, we would specify it in the code.)

| -> Thus, we get type assertions to be able to define the behavior of the program in terms of the possible values ​​we expect the program to provide during execution.

|-> Therefore, type assertions only apply to variables explicitly specified as interface types, not to variables that may implement the same interface but are not explicitly specified as interface types

Because of

We only need this type assertion at runtime when we use interfaces because we don't know the exact type of data that will be sent to the program - This type assertion is only needed when using interfaces, so type assertions are only works for types explicitly specified as interface types, since in all other cases the data types are known (allowing the compiler to implicitly assume that the variable implements the interface - since it already knows all the data types of the data involved) we There is no need to use type assertions on data of known types at all.

The above is the detailed content of What's the reasoning behind Go's "type assertion" approach?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:stackoverflow.com. If there is any infringement, please contact admin@php.cn delete