Home >Backend Development >Golang >Go: How to use interfaces in maps and slices

Go: How to use interfaces in maps and slices

PHPz
PHPzforward
2024-02-10 20:57:081271browse

Go: How to use interfaces in maps and slices

php editor Apple will introduce how to use interfaces in maps and slices. In modern web development, maps and slicing are common functional requirements. Using interfaces can make map and tile operations more flexible and scalable. This article will explain in detail the concept of interfaces and how to use interfaces to implement various functions in maps and tiles. By reading this article, you will learn how to optimize the use of maps and tiles to improve user experience and performance. Let’s explore this interesting topic together!

Question content

I need an interface mapping because I want to be able to run a function that can use a concrete implementation of either interface, without caring about the "extra" operations these structures can perform.

I read https://jordanorelli.com/post/32665860244/how-to-use-interfaces-in-go, it has a good explanation of pointers and interfaces, but I still don't know how to do it in practice Accomplish what I want.

I'm trying the following code:

https://play.golang.com/p/nrh2iyk7t9f

package main

import (
    "fmt"
)

type iexample interface {
    getname() string
}

type concrete struct {
    name string
}

func (c *concrete) getname() string {
    return c.name
}

func main() {
    // in my real application this is a slice returned from gorm orm
    var s = []concrete{
        concrete{name: "one"},
        concrete{name: "two"},
    }

    foo := make(map[string]iexample)
    bar := []iexample{}

    for _, c := range s {
        foo[c.name] = &c
        bar = append(bar, &c)
        fmt.printf("set key [%s]\r\n", c.name)
    }

    for name, element := range foo {
        fmt.printf("key: [%s] has element [%s]\r\n", name, element.getname())
    }
    for name, element := range bar {
        fmt.printf("key: [%d] has element [%s]\r\n", name, element.getname())
    }

}

Output:

set key [one]
set key [two]
key: [one] has element [two]
key: [two] has element [two]
key: [0] has element [two]
key: [1] has element [two]

What I really want is element one to be in key "one".

I think the problem occurs due to the assignment using the reference foo[c.name] = &c. I need this because otherwise I get the error "cannot use c (variable of type concrete) as iexample value in assignment: concrete does not implement iexample (method getname has pointer receiver)"

After reading https://dusted.codes/using-go-generics-to-pass-struct-slices-for-interface-slices, I wonder if I can use generics to solve the problem, but I can't solve it How to achieve.

type ExampleMap map[string]IExample

func (e *ExampleMap) add[T IExample](id string item T) {
    e[id] = item
}
// syntax error: method must have no type parameters

How to make this map contain the correct elements?

Solution

What you did is correct. You're just putting the wrong stuff into the map:

for i,c := range s {
        foo[c.Name] = &s[i]
        bar = append(bar, &s[i])
        fmt.Printf("Set key [%s]\r\n", c.Name)
    }

Loop variables are rewritten on each iteration, so when you add &c to the map and slice, the pointer you add is the address of c, which is in It will be overwritten on every iteration.

The above is the detailed content of Go: How to use interfaces in maps and slices. 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