如何在方案中通过引用传递变量?
我想要的功能示例:
(define foo
(lambda (&x)
(set! x 5)))
(define y 2)
(foo y)
(display y) ;outputs: 5
另外,有没有办法通过引用返回?
如何在方案中通过引用传递变量?
我想要的功能示例:
(define foo
(lambda (&x)
(set! x 5)))
(define y 2)
(foo y)
(display y) ;outputs: 5
另外,有没有办法通过引用返回?
请参阅http://community.schemewiki.org/?scheme-faq-language问题“有没有办法模拟 call-by-reference?”。
总的来说,我认为这与方案的功能性质作斗争,因此可能有更好的方法来构建程序以使其更像方案。
就像 Jari 所说,通常您希望避免在 Scheme 中通过引用传递,因为它表明您正在滥用副作用。
但是,如果你愿意,你可以将任何你想通过引用传递的东西放在一个cons
盒子里。
(cons 5 (void))
将产生一个包含 5 的框。如果您将此框传递给将 5 更改为 6 的过程,则您的原始框也将包含 6。当然,您必须记住cons
何时car
合适。
Chez Scheme(以及可能的其他实现)有一个称为box
(及其同伴box?
和unbox
)的过程,专门用于这种装箱/拆箱废话:http ://www.scheme.com/csug8/objects.html#./objects:s43
您可以使用宏:
scheme@(guile-user)> (define-macro (foo var)`(set! ,var 5))
scheme@(guile-user)> (define y 2)
scheme@(guile-user)> (foo y)
scheme@(guile-user)> (display y)(newline)
5
拉姆达!
(define (foo getx setx)
(setx (+ (getx) 5)))
(define y 2)
(display y)(newline)
(foo
(lambda () y)
(lambda (val) (set! y val)))
(display y)(newline)
Jari 是对的,通过引用传递有点不合时宜,至少对于变量来说是这样。然而,你想要的行为一直被使用,并且经常被鼓励,通过使用闭包以更像方案的方式。经验丰富的方案中的第 181 页和第 182 页(谷歌图书)做得比我能解释的要好。
这是一个参考,它提供了一个宏,允许您使用类似 ac 的语法来“通过引用传递”。Olegs 网站是有趣阅读的金矿,因此如果您还没有,请务必将其标记为书签。
您可以从外部上下文中定义的函数内影响外部上下文,这使您可以通过引用变量获得影响,即具有副作用的函数。
(define (outer-function)
(define referenced-var 0)
(define (fun-affects-outer-context) (set! referenced-var 12) (void))
;...
(fun-affects-outer-context)
(display referenced-var)
)
(outer-function) ; displays 12
该解决方案限制了副作用的范围。
否则有Eli的子评论中提到的(define x (box 5))、(unbox x)等,与erjiang建议的cons解决方案相同。
你可能使用了太多的 C、PHP 或其他东西。在方案中,您不想做诸如 pass-by-* 之类的事情。首先了解范围的含义以及不同实现的行为方式(特别是尝试找出 LISP 和 Scheme 之间的区别)。
本质上,纯函数式编程语言没有副作用。因此,这意味着 pass-by-ref 不是一个功能概念。