0

我构造了一个函数,命名find-all为通过“递归”查找系列中给定项目的所有索引。第一次调用find-all给出正确的输出。但是,从第二次调用开始,所有输出都附加在一起。

find-all: function [series found][
result: [] 
  either any [empty? series none? s-found: find series found]
     [result]
     [append result index? s-found
      find-all next s-found found]
]

;; test:
probe find-all "abcbd" "b"   ;; output [2 4] as expected
probe find-all [1 2 3 2 1] 2  ;; output [2 4 2 4]

既然用创建的函数内部的变量function是局部的,为什么result在以后的函数调用中变量的值仍然存在,导致第二result次调用的find-all不是以 开头[]?实现此功能的正确递归方式是什么?

4

2 回答 2

3

如果您find-all在拨打这两个电话后进行检查,答案是显而易见的:

>> ?? find-all
find-all: func [series found /local result s-found][
    result: [2 4 2 4] 
    either any [empty? series none? s-found: find series found] 
    [result] 
    [append result index? s-found 
        find-all next s-found found
    ]
]

result是一个间接值,它的数据缓冲区存储在堆上。数据在调用之间被保留并累积,因为你没有重新创建它copy——result函数上下文的本地与此无关。

于 2021-04-02T08:31:48.137 回答
0

感谢@9214 的帮助,尤其是关于indirect value. 我给出这样的解决方案:

find-all: function [series found][
  either any [empty? series none? s-found: find series found]
     [[]]
     [append
        reduce [index? s-found]
        find-all next s-found found
    ]
]

;; test:
probe find-all "abcbd" "b"   ;; output [2 4] as expected
probe find-all [1 2 3 2 1] 2  ;; output [2 4] as expected
于 2021-04-02T09:40:30.690 回答