gpt4 book ai didi

go - 为什么这段代码会失败?

转载 作者:IT王子 更新时间:2023-10-29 01:40:18 25 4
gpt4 key购买 nike

我已经用 FP 风格编写了一些 go 代码来生成素数:

package main
import (
"fmt"
)

func gen_number_stream() func() (int, bool) {
i := 1
return func() (int, bool) {
i += 1
return i, true
}
}

func filter_stream(stream func() (int, bool), f func(int) bool) func() (int, bool) {
return func() (int, bool) {
for i, ok := stream(); ok; i, ok = stream() {
if f(i) {
return i, true
}
}
return 0, false
}
}

func sieve(stream func() (int, bool)) func() (int, bool) {
return func() (int, bool) {
if p, ok := stream(); ok {
remaining := filter_stream(stream, func(q int) bool { return q % p != 0 })
stream = sieve(remaining)
return p, true
}
return 0, false
}
}


func take(stream func() (int, bool), n int) func() (int, bool) {
return func() (int, bool) {
if n > 0 {
n -= 1
return stream()
}
return 0, false
}
}

func main() {

primes := take(sieve(gen_number_stream()), 50)

for i, ok := primes(); ok; i, ok = primes() {
fmt.Println(i)
}

}

当我运行这段代码时,它变得越来越慢,最后出现如下运行时错误:

runtime: out of memory:  [...]

这是 python 代码的一个版本,它运行良好:

def gen_numbers():
i = 2
while True:
yield i
i += 1

def sieve(stream):
p = stream.next()
yield p
for i in sieve( i for i in stream if i % p != 0 ):
yield i

def take(stream,n):
for i,s in enumerate(stream):
if i == 50: break
yield s

def main():
for i in take(sieve(gen_numbers()),50):
print i


if __name__ == '__main__':
main()

我想知道为什么以及如何修复它。是我的代码还是golang编译器的问题?谢谢!

PS:抱歉我的英语不好。

最佳答案

问题是您的递归筛选函数。我怀疑您通过在循环中不断递归调用 sieve 来破坏堆栈。

func sieve(stream func() (int, bool)) func() (int, bool) {
return func() (int, bool) {
if p, ok := stream(); ok {
remaining := filter_stream(stream, func(q int) bool { return q % p != 0 })
stream = sieve(remaining) // just keeps calling sieve recursively which eventually blows your stack.
return p, true
}
return 0, false
}
}

关于go - 为什么这段代码会失败?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12071040/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com