Golang Interface empty interface type conversion

Golang Interface empty interface type conversion

Recently, I have written a lot of Golang code at work. I didn’t know much about Golang before, but now I am learning while writing, and slowly dabbling in some Golang content. Let’s take a look at the Interface in Golang today, that is, the interface

01

interface brief introduction

1. What is an interface?

In Golang, interface means interface.

An interface is actually a collection of methods. It is an abstract concept, and it is easier to understand it with examples.

For example, the following code, inter, is an interface and contains two methods, func1 and func2:

import "fmt"

// inter is an interface that contains two methods func1 and func2
type inter interface {    
    func1()    
    func2()
}
copy

2. Features of the interface

a. The methods in the interface have no method body, and there are no variables in the interface definition;

b. The interface does not need to be explicitly implemented (that is, there is no implement keyword). As long as a certain type implements the method of the interface, we say that this type implements the interface.

The following code, the impl type, implements the inter interface:

import "fmt"
// inter is an interface that contains two methods func1 and func2
type inter interface {
    func1()
    func2()
}

// Customize the impl type and implement the func1 method
type impl struct{}

func (i *impl) func1() {
    fmt.Println("impl func1")
}
func (i *impl) func2() {
    fmt.Println("impl func2")
}

func main() {
    var a = &impl{}
    a.func1()
    a.func2()
}
copy

The output is as follows:

impl func1
impl func2
copy

c. The interface itself cannot be instantiated.

d. The interface can point to a custom variable that implements the interface. This variable can be a structure or a common type, such as int, but it must be custom

as follows:

type inter interface {    func1()
    func2()
}

// Customize the myint type and implement the func1 and func2 methods
type myint int
func (m *myint) func1() {
    fmt.Println("myint func1")
}
func (m *myint) func2() {
    fmt.Println("myint func2")
}

func main() {
    var b myint = 0
    b.func1()
    b.func2()

    var d inter = &b
    fmt.Println(d)
}


copy

The output is as follows:

myint func1
myint func2
copy

In the above code, the type of variable b is myint, which is essentially of type int. myint implements the interface inter, so variable b can be directly assigned to variable d of type inter

e. A custom type can implement multiple interfaces.

f. Interfaces can be inherited. If a type wants to implement a sub-interface, it needs to implement all the methods of the parent interface.

g. An interface containing 0 methods is called an empty interface, and all types implement the empty interface.

The most classic example of an empty interface may be the printing function fmt.Println, and its code is as follows:

import (
    "fmt"
)

func main() {

    //1. fmt.Println() function definition, pass in an any parameter
    //func Println(a ...any) (n int, err error) {
    //  return Fprintln(os.Stdout, a...)
    //}

    //2. any is actually the type of interface{}
    // any is an alias for interface{} and is equivalent to interface{} in all ways.
    //type any = interface{}


    var a int = 0
    var b float32 = 1.2
    fmt.Println(a, b)
}
copy

In the above example, the Println function can print any type of parameter passed in. In fact, because all types implement the empty interface interface{}, all types can be printed through fmt.Println.

02

Empty interface type conversion method

With the above foundation, we can start today's topic. If the parameter of a function is an empty interface type, then this function can accept parameters of any type.

But it needs to be clear that the parameters of the empty interface type can be passed in any type, but the empty interface is not equal to other types.

If a function uses an empty interface as a parameter, and we want to get the parameter and perform related operations (such as string interception, number auto-increment, etc.), we need to know the real type of the parameter before we can do specific operations, otherwise The code may panic directly.

Let's look at a piece of problematic code:

We call the inter2Type function in the main function, the parameter is passed in the number 1, and then this function adds 1 to the number 1. It can be found that the syntax prompt interface{} type cannot be directly incremented because it is not an int type.

The correct way to write it is as follows:

func interface2Type(i interface{}) {
   switch i.(type) {
   case string:
      fmt.Println("string", i.(string)+" function")
      break
   case int:
      fmt.Println("int", i.(int)+1)
      break
   case float64:
      fmt.Println("float64", i.(float64)+1.0)
      break
   default:
      fmt.Println("this kind of type is not support")
   }
}

func main() {

   interface2Type("Test")
   interface2Type(1)
   interface2Type(1.0)

   var a float32 = 1
   interface2Type(a)}
copy

First judge the real type of the interface{} parameter, and then perform the corresponding operation.

If it is string, it will be concatenated; if it is int or float64, it will add 1.

Here, our function is only compatible with the three types of string, int, and float64. In fact, there are far more data types. If there are other types of functions, we can set the default function in the switch case statement to filter other types. For example, in the above example, the float32 type we passed in at the end, the output result is:

string Test function
int 2
float64 2
this kind of type is not support
copy

In fact, there are still many cases related to Golang interface, you can go to the official website to check.

I have done a lot of development, and I have summed up a learning method, that is, learning this development language is the same as learning MySQL. Official documents are always first-hand information, which refers to repeated chewing.

That's it for today.

Tags: Go

Posted by ezekiel on Wed, 07 Dec 2022 04:57:33 +0300