【发布时间】:2017-12-09 19:00:00
【问题描述】:
所以我是 Golang 的超级新手,并且看到围绕该语言的热门话题似乎是并发性,我想一个让我的脚趾湿透的好方法是编写一个通用的 map 函数。在伪代码中:
map(F funtion,A array){
return([F(k) for k in A])
}
显然我希望每个 F(k) 的计算同时发生。对于组织,我有一个包含我的实现的主文件和一个包含我所需定义的支持文件 Mr。
.
├── main.go
└── Mr
└── Mr.go
Main 是一个简单的测试实现,它应该将字符串数组转换为整数数组,其中结果的每个成员都是输入数组中相应字符串的长度。
package main
import(
"fmt"
"./Mr"
)
func exfunc(i int, c chan int){
c<-i
}
func main(){
data := make(map[int]string)
data[1]="these"
data[2]="are"
data[3]="some"
data[4]="words"
data[5]="and a few more..."
f := func(w string)int{
return(len(w))
}
testMr := Mr.Map(f,data) // this is line 22 (matters later)
fmt.Println(testMr)
}
鉴于我明确指定了所有类型,这对我的 Mr.Map 函数非常有效。
package Mr
type result struct{
key,value int
}
func wrapper(f func(string) int,k int,v string, c chan result){
c <- result{k,f(v)}
}
func Map(f func(string) int,m map[int]string) map[int]int{
c := make(chan result)
ret := make(map[int]int)
n := 0
for k := range m{
go wrapper(f,k,m[k],c)
n++
}
for ;n>0; {
r := <-c
ret[r.key]=r.value
n--
}
return(ret)
}
但是我希望我能够用空接口概括这个映射。
package Mr
type T interface{}
type result struct{
key,value T
}
func wrapper(f func(T) T,k T,v T, c chan result){
c <- result{k,f(v)}
}
func Map(f func(T) T,m map[T]T) map[T]T{
c := make(chan result)
ret := make(map[T]T)
n := 0
for k := range m{
go wrapper(f,k,m[k],c)
n++
}
for ;n>0; {
r := <-c
ret[r.key]=r.value
n--
}
return(ret)
}
不幸的是,当我使用这个泛化 Mr.Map 运行 main 时,我收到以下错误。
# command-line-arguments
./main.go:22: cannot use f (type func(string) int) as type func(Mr.T) Mr.T in argument to Mr.Map
./main.go:22: cannot use data (type map[int]string) as type map[Mr.T]Mr.T in argument to Mr.Map
是的,显然我明白错误告诉我什么,但我不得不为键和值类型的每种可能组合重新编写我的 Map 函数似乎很疯狂。
Is there a work around here, or is this just the nature of the beast?
【问题讨论】:
-
虽然您的计数器可以正常工作,但有一个内置类型可以管理它,
sync.WaitGroup,值得一看。
标签: go concurrency mapreduce