Using maps/hashes and empty interfaces in Go(lang) to flexibly store and access data
I have recently explored flexible data storage in Go using byte arrays. Since then I have discovered the power on map
(basically, hash) data structures in Go.
I have also discovered more capabilities embedded in the empty interface (interface{}
) concept. Not only can it store any data type, including functions represented as variables, but also the type stored can be properly extracted and then utilized.
I am sorry, being a bit burned out after a number of hours of playing with the code I guess the best I can do for now is just illustrate these concepts by way of a quick example.
package main
import(
"fmt"
)
// Increment function
func incr(i int)int{
return i + 1
}
// Decrement function
func decr(i int)int{
return i - 1
}
func main(){
//Initialize the master map (hash)
m := make(map[uint32]map[interface{}]interface{})
// Initialize a value as a map
m[1] = make(map[interface{}]interface{})
m[1]["func"] = incr
m[1]["value"] = 1
m[1]["animal"] = "dog"
m[2] = make(map[interface{}]interface{})
m[2]["func"] = decr
m[2]["value"] = 10
// Convert empy interface to the function as a vairable
fnc, ok := m[2]["func"].(func(int)int)
// Using "ok" boolean to avoid an error message
if ! ok{
fmt.Println("Ouch, something's wrong!")
}
// Extracting the int value out of empty interface (interface{})
arg, ok := m[2]["value"].(int)
// Running function stored as a variable in a hash against a
// variable stored as a value in the same hash.
// Storing it in a different hash pair.
m[2]["mod_value"] = fnc(arg)
// Extracting the function reference value out of
// empty interface (interface{})
fnc, ok = m[1]["func"].(func(int)int)
// Extracting the int value out of empty interface (interface{})
arg, ok = m[1]["value"].(int)
// Running function stored as a variable in a hash against a
// variable stored as a value in the same hash.
// Storing it in the same hash pair.
m[1]["value"] = fnc(arg)
m[2]["cat"] = "Fluffy"
for key, value := range(m){
for k1, v1:= range(value){
fmt.Printf("m = %d %s %s\n", key, k1, v1)
}
}
}
The program above is basically a play session with assigning values to a map
and using these values, including running a function recorded into a map
on other contents of the same map
.
Feel free to explore it further in the Go Playground.
This opens a whole new world of possibilities to both flexibly storing and modifying data using a uniform representation model.
References
Go Playground - sample map
modification/access program
@borepstein
Go(lang) adventure: flexibly storing data of all sorts as byte arrays
@borepstein, 4 October 2021
Maps explained: create, add, get, delete
yourbasic.org/golang
Type Assertion and Type Conversion in Golang
Akash Jain, Medium, 10 August 2020
Social media links
Website
Support
PIZZA Holders sent $PIZZA tips in this post's comments:
@pixresteemer(8/10) tipped @borepstein (x1)
Learn more at https://hive.pizza.