Using functional options instead of method

2

I tried the below, and it worked well:

package main

import "fmt"

type T interface {
}

type hashMap struct {
    m    map[T]T
    k    []T
}

func (h *hashMap) From(m map[T]T) {
    h.m = m
    h.k = make([]T, len(m))
    i := 0
    for key := range m {
        h.k[i] = key
        i++
    }
}

func main() {
    inv := new(hashMap)
    inv.From(map[T]T{"first": 1})
    fmt.Printf("%v", inv)
}

The output was correct as expected:

&{map[first:1] [first]}

I'm looking for a way where I can write:

inv := new(hashMap).from(map[T]T{"first": 1})
// instead of:
//  inv := new(hashMap)
//  inv.From(map[T]T{"first": 1})

So, I re-wrote the code as below:

package main

import "fmt"

type T interface {
}

type hashMap struct {
    m    map[T]T
    k    []T
    from func(m map[T]T) hashMap    // <---- new
} 

func from(m map[T]T) hashMap {        // <----- change of func signature
    h := new(hashMap)
    h.m = m
    h.k = make([]T, len(m))
    i := 0
    for key := range m {
        h.k[i] = key
        i++
    }
    return *h
}

func main() {
    inv := new(hashMap).from(map[T]T{"first": 1})
    fmt.Printf("%v", inv)
}

But I got the below output:

panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xc0000005 code=0x0 addr=0x0 pc=0x49c2c2]

goroutine 1 [running]:
main.main()
    d:/goplay/hashmap.go:55 +0xf2
exit status 2

Any idea how to get it done the way I'm looking for?

go

1 Answer

2

You are very close to getting it! First, since you already create the hashMap in main() you don't need to create again in from(). Just delete line 14 and change the signature of from() like this:

func (h *hashMap) from(m map[T]T) hashMap {

Also delete line 11 - in Go you don't need to declare a method of a type just define it.

Try it in the playground

Also it's idiomatic to build a slice using append:

func (h *hashMap) from(m map[T]T) hashMap {
    h.m = m
    h.k = make([]T, 0, len(m))
    for key := range m {
        h.k = append(h.k, key)
    }
    return *h
}
answered on Stack Overflow Jun 2, 2020 by AJR • edited Jun 2, 2020 by AJR

User contributions licensed under CC BY-SA 3.0