如何在Racket中避免代码重复?附重复代码示例及疑问
嘿,我完全懂你说的这种重复代码闹心的感觉!在Scheme这类函数式语言里,咱们照样能像过程式语言那样用局部变量来消除冗余调用,不用反复跑同一个表达式。
先看看你原来的代码里的重复点:(sublist-numbers mixedList)被调用了三次,(first (sublist-numbers mixedList))又重复了两次——不仅冗余,要是sublist-numbers是个处理开销大的函数,还会影响效率。
给你几种常用的解决办法:
1. 用let做局部绑定(并行绑定)
let可以一次性把需要的结果绑定到变量上,所有绑定的表达式会先计算好,再进入代码块使用:
(define (get-min&max-from-mixed-list mixedList) (let ((num-list (sublist-numbers mixedList))) (if (null? num-list) '() (let ((first-num (first num-list))) (min&maxRec num-list first-num first-num)))))
这里先把过滤后的数字列表存到num-list里,确认非空后再把第一个元素存到first-num,这样每个表达式只计算一次。
2. 用let*简化嵌套(串行绑定)
如果后面的变量依赖前面的绑定结果,let*可以按顺序绑定,省去一层嵌套:
(define (get-min&max-from-mixed-list mixedList) (let* ((num-list (sublist-numbers mixedList)) (first-num (first num-list))) (if (null? num-list) '() (min&maxRec num-list first-num first-num))))
let*会先计算num-list,再用它来计算first-num,代码看起来更清爽。
3. 用内部define(部分Scheme方言支持,比如Racket)
有些Scheme实现允许在函数内部直接用define来声明局部变量,和let*效果类似,写法更贴近过程式的变量声明:
(define (get-min&max-from-mixed-list mixedList) (define num-list (sublist-numbers mixedList)) (define first-num (first num-list)) (if (null? num-list) '() (min&maxRec num-list first-num first-num)))
这种写法可读性很高,就像你在过程式里先声明变量再用一样。
需要注意的是:因为咱们先判断了num-list不为空才去取first-num,所以不会出现空列表取第一个元素的错误,完全安全。
内容的提问来源于stack exchange,提问作者Tomer
相关产品推荐
相关产品推荐

