Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Oop 球拍相当于python';s_uuurepr_uuuu_uuu和uuu str_uuu?_Oop_Racket - Fatal编程技术网

Oop 球拍相当于python';s_uuurepr_uuuu_uuu和uuu str_uuu?

Oop 球拍相当于python';s_uuurepr_uuuu_uuu和uuu str_uuu?,oop,racket,Oop,Racket,在python对象中,重写对象的方法\uuuu repr\uuu和\uu str\uuu可以分别提供对象的“明确”和“人类可读”表示。如何在球拍中实现类似的行为 我遇到了可打印的界面,它似乎可以用于此目的,但我一直无法让它完全按照我的预期工作。基于文档中的标准“鱼”示例: (define fish% (class* object% (printable<%>) (init size) ; initialization argument (super-new) ;

在python对象中,重写对象的方法
\uuuu repr\uuu
\uu str\uuu
可以分别提供对象的“明确”和“人类可读”表示。如何在球拍中实现类似的行为

我遇到了
可打印的
界面,它似乎可以用于此目的,但我一直无法让它完全按照我的预期工作。基于文档中的标准“鱼”示例:

(define fish%
  (class* object% (printable<%>)
    (init size) ; initialization argument
    (super-new) ; superclass initialization
    ;; Field
    (define current-size size)

    ;; Public methods
    (define/public (get-size)
      current-size)
    (define/public (grow amt)
      (set! current-size (+ amt current-size)))
    (define/public (eat other-fish)
      (grow (send other-fish get-size)))

    ;; implement printable interface
    (define/public (custom-print port quoting-depth)
      (print "Print called!"))
    (define/public (custom-write port)
      (print "Write called!"))
    (define/public (custom-display port)
      (print "Display called!"))))
因此,问题有三个方面:

  • 为什么它会这样做,即在对象的一个明显的单一呈现上调用多个方法

  • 自定义打印、自定义写入和自定义显示的计算方法应该是什么?它们应该仅仅返回一个字符串,还是实际上会产生打印、书写或显示(视情况而定)的副作用?例如,自定义写入方法是否应在内部调用
    write
    函数

  • 这是用于此目的的正确构造吗?如果没有,是否有/是什么

  • 至于

  • 为什么它会这样做,即在对象的一个明显的单一呈现上调用多个方法
  • 您在
    write
    中意外使用了
    print
    ,因此写入值时,将首先打印值

    (define/public (custom-write port)
       (print "Write called!"))
    
    显示
    中也存在类似问题

    还要记住打印/写入/显示到正确的端口

    试一试


    另一个答案已经帮助您找到了代码中的问题,您需要使用给定的端口作为参数,而不是隐式的
    (当前输出端口)
    ——但是解释不太正确。要按相反顺序解决问题,请执行以下操作:

  • 这是用于此目的的正确构造吗?如果没有,是否有/是什么
  • 是的,
    printable
    是用于自定义基于类对象的打印的正确构造。更一般地说,非类的结构类型可以自定义打印,例如通过
    gen:custom write
    通用接口或低级
    prop:custom write
    struct type属性,该属性用于实现
    printable

  • 自定义打印、自定义写入和自定义显示的计算方法应该是什么?它们应该仅仅返回一个字符串,还是实际上会产生打印、书写或显示(视情况而定)的副作用?例如,自定义写入方法是否应在内部调用写入函数
  • 这些方法实际上应该在作为参数提供的端口上执行IO的副作用。他们应该在内部使用相应的函数(例如
    write
    用于
    custom write
    print
    用于
    custom print
    )递归打印/写入/显示字段中的值。另一方面,当直接发送特定字符时,它们通常应使用诸如
    写入字符
    写入字符串
    、或
    打印F
    之类的函数。给出一个打印为
    的元组数据类型的示例:它对尖括号和逗号使用
    写入字符串
    ,但对元组元素使用递归
    打印
    /
    写入
    显示

  • 为什么它会这样做,即在对象的一个明显的单一呈现上调用多个方法
  • 这是你问题中最复杂的部分。在Racket中打印可以通过几个挂钩进行自定义:有关一些示例,请参阅、和。许多定制挂钩在生成输出的过程中使用中间端口

    有一件事不是解释的一部分,那就是您在实现中使用了
    print
    ,尤其是
    print
    通过词法范围绑定到正常的Racket函数,而不是对象的方法

    作为一个例子,考虑以下示例的修改,它将报告给<代码>(当前输出端口)< /代码>作为方法的参数的端口的标识:

    #朗球拍
    (定义报告)
    (let([下一个id 0]
    [id缓存(生成哈希)])
    (λ(op端口)
    (printf“~a~a~v\n”
    op
    (哈希参考id缓存)
    港口
    (λ ()
    (定义下一个id)
    (哈希集!id缓存端口id)
    (设置!下一个id(添加1下一个id))
    同上)
    港口))
    (定义鱼的百分比)
    (类*对象%(可打印)
    (超新)
    实现可打印接口
    (定义/公共(自定义打印端口引用深度)
    (报告“自定义打印”端口)
    (定义/公共(自定义写入端口)
    (报告“自定义写入”端口)
    (定义/公共(自定义显示端口)
    (报告“自定义显示”端口)))
    (定义f(新鱼%)
    F
    (打印f)
    (新行)
    (显示f)
    (新行)
    (写f)
    
    在DrRacket中,这将生成输出:

    custom-display 0 #<output-port:null>
    custom-display 1 #<output-port:null>
    custom-print   2 #<printing-port>
    
    custom-display 3 #<output-port:null>
    custom-display 4 #<output-port:null>
    custom-print   5 #<printing-port>
    
    custom-display 6 #<output-port:null>
    custom-display 7 #<printing-port>
    
    custom-display 8 #<output-port:null>
    custom-write   9 #<printing-port>
    
    自定义显示0#
    自定义显示1#
    自定义打印2#
    自定义显示3#
    自定义显示4#
    定制打印5#
    自定义显示6#
    自定义显示7#
    自定义显示8#
    自定义写入9#
    
    在命令行中,输出为:

    $ racket demo.rkt 
    custom-write   0 #<output-port:null>
    custom-print   1 #<output-port:redirect>
    
    custom-write   2 #<output-port:null>
    custom-print   3 #<output-port:redirect>
    
    custom-display 4 #<output-port:null>
    custom-display 5 #<output-port:redirect>
    
    custom-write   6 #<output-port:null>
    custom-write   7 #<output-port:redirect>
    
    $racket demo.rkt
    自定义写入0#
    自定义打印1#
    自定义写入2#
    定制打印3#
    自定义显示4#
    自定义显示5#
    自定义写入6#
    自定义写入7#
    
    “您不小心在write中使用了print,因此写入值时,将首先打印值。”--那里的print语句实际上是为了跟踪,它只是打印字符串,而不是对象本身。它是否仍然会在对象上使用打印方法?此外,跟踪输出中命中的方法顺序似乎与该假设不符。同时,提姆
    > (define f (new fish% [size 10]))
    > f
    "Print 10\n"
    > (display f)
    Display 10
    > (write f)
    "Write 10\n"
    
    custom-display 0 #<output-port:null>
    custom-display 1 #<output-port:null>
    custom-print   2 #<printing-port>
    
    custom-display 3 #<output-port:null>
    custom-display 4 #<output-port:null>
    custom-print   5 #<printing-port>
    
    custom-display 6 #<output-port:null>
    custom-display 7 #<printing-port>
    
    custom-display 8 #<output-port:null>
    custom-write   9 #<printing-port>
    
    $ racket demo.rkt 
    custom-write   0 #<output-port:null>
    custom-print   1 #<output-port:redirect>
    
    custom-write   2 #<output-port:null>
    custom-print   3 #<output-port:redirect>
    
    custom-display 4 #<output-port:null>
    custom-display 5 #<output-port:redirect>
    
    custom-write   6 #<output-port:null>
    custom-write   7 #<output-port:redirect>