【问题标题】:How do I return a copy of an object?如何返回对象的副本?
【发布时间】:2011-02-24 10:38:17
【问题描述】:

我需要实现一个有一个参数的函数 -- obj -- 它返回一个 Scheme 表达式,当计算该表达式时,将返回一个 obj 的副本。

关于如何解决问题的任何想法?

【问题讨论】:

  • 你是什么意思?
  • 为什么不直接返回 obj?我假设您正计划进行破坏性修改。为什么不创建一个返回修改后副本的函数,然后用延续包装它以提供您想要的行为?

标签: scheme racket r6rs


【解决方案1】:

我猜你的意思是写“一个函数 expr-returning [接受] obj [and] 返回一个 Scheme 表达式,当评估时,......”

假设是这样:您真正需要的是设计秘诀。首先:写下你的函数接受什么以及它返回什么的例子。这将阐明您想要对他人和(可能更重要的)您自己做的事情。

希望这会有所帮助;抱歉这么不透明...

【讨论】:

    【解决方案2】:

    如果您希望您的过程能够复制任何对象,那么该对象可以是 Scheme 的 basic types. 中的任何一种。由于不同的类型,它们具有不同的“性质”,或者结构,或者你有什么,因此复制一种类型的对象必然会涉及与复制另一种不同类型的对象不同的策略。

    因此,您处理此问题的方法是检查每个 Scheme 的类型(或者更确切地说,您关心处理的 Scheme 类型的子集)并弄清楚复制该类型的对象意味着什么。如果您以明显的方式执行此操作,则最终应该得到一组专门的程序,例如 COPY-NUMBER、COPY-SYMBOL 等(剧透:很多这些程序不会很有趣。)

    要将这些专门的过程合并为一个可以复制您提供的任何对象的单一过程,减少到确定对象的真实类型并调用 COPY-FOO 过程来完成工作(您也可以内联扩展过程)。您可以使用 COND 和类型确定谓词非常轻松地组织它:

    (define (copy-object obj)
      (cond ((number? obj) (copy-number obj))
            ((boolean? obj) (copy-boolean obj))
            ...
            ))
    

    这是一种通用设计模式,用于对数据执行操作,而不管其类型如何,称为“类型分派”。这实际上是一种非常糟糕的泛型编程方式,但在这种情况下这并不重要。

    最后一件事是返回一个你可以评估以获得副本的东西。不妨直截了当地告诉您:将对 COPY-OBJECT 的调用封装在无参数的 lambda 表达式中:

    (define (expr-returning obj)
      (lambda () (copy-object obj)))
    

    然后你可以做类似的事情

    诡计>(定义 x(列表 1 2 3 4)) guile> (define y (expr-returning x)) 诡计>(定义cx(y)) 诡计> x (1 2 3 4) 诡计>cx (1 2 3 4) 诡计> (set-cdr!x 'foo) 诡计> x (1 . foo) 诡计>z (1 2 3 4) 等等

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-07-24
      • 2020-01-18
      • 1970-01-01
      • 2011-01-21
      • 1970-01-01
      • 2010-09-13
      • 1970-01-01
      相关资源
      最近更新 更多