Golang中使用函数式选项替代方法的实践探讨
Golang中使用函数式选项替代方法的实践探讨 我尝试了以下代码,效果很好:
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)
}
输出结果符合预期:
&{map[first:1] [first]}
我正在寻找一种写法,能够实现:
inv := new(hashMap).from(map[T]T{"first": 1})
// 而不是:
// inv := new(hashMap)
// inv.From(map[T]T{"first": 1})
因此,我将代码重写如下:
package main
import "fmt"
type T interface {
}
type hashMap struct {
m map[T]T
k []T
from func(m map[T]T) hashMap // <---- 新增
}
func from(m map[T]T) hashMap { // <----- 函数签名变更
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)
}
但我得到了以下输出:
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
有什么办法能实现我想要的写法吗?
更多关于Golang中使用函数式选项替代方法的实践探讨的实战教程也可以访问 https://www.itying.com/category-94-b0.html
1 回复
更多关于Golang中使用函数式选项替代方法的实践探讨的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
要实现链式调用,可以使用函数式选项模式。以下是修改后的代码:
package main
import "fmt"
type T interface{}
type hashMap struct {
m map[T]T
k []T
}
// 返回*hashMap以支持链式调用
func (h *hashMap) From(m map[T]T) *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)
}
如果希望使用函数式选项模式进行更灵活的配置:
package main
import "fmt"
type T interface{}
type hashMap struct {
m map[T]T
k []T
}
type Option func(*hashMap)
func WithMap(m map[T]T) Option {
return func(h *hashMap) {
h.m = m
h.k = make([]T, len(m))
i := 0
for key := range m {
h.k[i] = key
i++
}
}
}
func NewHashMap(opts ...Option) *hashMap {
h := &hashMap{}
for _, opt := range opts {
opt(h)
}
return h
}
func main() {
// 使用函数式选项
inv := NewHashMap(WithMap(map[T]T{"first": 1}))
fmt.Printf("%v", inv)
// 支持多个选项的扩展
inv2 := NewHashMap(
WithMap(map[T]T{"first": 1, "second": 2}),
)
fmt.Printf("%v", inv2)
}
输出:
&{map[first:1] [first]}
&{map[first:1 second:2] [first second]}

