Validate architecture containing map of interface pointers


(Altu Faltu) #1

So here is what I am trying to do.
A single Ledger .Which is of the type

map[string]interface{}

The problem is every-time anyone wants to read from the ledger he has to copy the value to a local variable and perform operations on it. This ‘copy’ might might lead to performance issues in my project.

Instead I want the map of hold references of the object which is inserted into it. This way anyone using the map doesnt have to copy into local variable rather point to the original object/modify the original object(its okay to modify) and get things done.Therefore changing the map structure to

map[string]*interface{}

Now the question : Is this the right thinking? Does golang gives any other alternate tool/mechanism to implement what I am willing to do?

Moving on , now if I try this , its failing

s:= "some random string"
singleLedger := make(map[string]*interface{})
singleLedger["first_entry"] = &s

What is going wrong?
What I want to do is it possible?
https://play.golang.org/p/KqqUjCHpRTz


(Norbert Melzer) #2

Just make int map[string]interface{} and only store pointers.

Wrap getting and setting values into functions/methods and guarantee through them that only pointers get stored.

Alternatively, you could make s an interface{}, I’m not sure though if you can reconstruct its original type then. https://play.golang.org/p/DIagkFCm_lB


(Altu Faltu) #3

Thanks @NobbZ

What would the definition look like?

func (l *Ledger) AddElement(key string, value interface{}){
//how to wrap the interface within an interface pointer?
}

(Christophe Meessen) #5
func (l *Ledger) AddElement(key string, value interface{}){
    if reflect.ValueOf(value).Kind() != reflect.Ptr {
        panic("AddElement accept only a pointer value")
    }
    // ...
}

(Altu Faltu) #6

I am guessing @Christophe_Meessen this is the second approach to ensure the functionality after what @NobbZ mentioned. Bit skeptical using reflection.


(Altu Faltu) #8

Creating a small example which depicts the implementation.However its creating a copy object not a pointer.
https://play.golang.org/p/AXWNo7X069f

package main

import (
"fmt"
)

type Ledger struct {
kvm map[string]*interface{}
}

func NewLedger() *Ledger {

return &Ledger{kvm: make(map[string]*interface{})}
} 

func (l *Ledger) AddToLedger(key string, val *interface{}) {
l.kvm[key] =val
}

func (l *Ledger) ReadFromLedger(key string) *interface{} {
return l.kvm[key]
}



func main() {

s:=NewLedger()

str:=interface{}("some random string")

s.AddToLedger("first",&str)

ledgerPtrInterfaceType:=s.ReadFromLedger("first")
ledgerPtrStringType:=(*ledgerPtrInterfaceType).(string)// is this creating a new 'copy' object? 

fmt.Println(ledgerPtrStringType)
str ="updated"
fmt.Println("updated_string:",ledgerPtrStringType)//the string is not updated, what am I missing?

}