例如,当我在列表printf
上使用过程'((2 t r d))
时,输出中的最后一行是
'(#<void>)
和'(#<void>)
出现的次数取决于嵌套列表的数量。你能帮我解释一下吗???
这是我的printf功能
(define counting
(lambda (lst)
(if (null? lst)
'()
(printf "~a, ~s\n" (car lst) (length (cdr lst))))))
我尝试了其他程序,例如fprintf
并使用此表格
(fprintf (current-output-port) "~a, ~s\n" (car lst) (length (cdr lst)))
同样的事情发生了!
答案 0 :(得分:1)
AFAIK Scheme标准中没有此类过程,因此您可能需要为具有该标准的实现添加标记。我知道racket
有printf
。
单独(display x)
(以及球拍中的(printf x)
通常不显示,因此产生(#<void>)
的内容不在问题中。在Scheme中,每个过程都计算为一个值。为了说明这一点,请尝试:
(map display '(1 2 3 4))
这将返回一个包含4个未指定值的列表,因为map会显示结果列表。 display
(以及球拍中的printf
)打印参数评估的结果,但不需要返回任何内容,因为标准没有说应该。大多数实现通过返回一个未定义的对象来做到这一点,但有些实际上也返回了参数。它们的主要功能是在屏幕上显示某些内容以及它已经完成的副作用。为了忽略返回值,您可以使用for-each
来映射副作用。
(for-each display '(1 2 3 4))
当在Scheme中说这是正常的,每个过程都返回一些内容,并且你通过REPL打印返回值来误读输出。
答案 1 :(得分:0)
你说'输出的最后一行是'(#<void>)
- 这是因为你的Scheme环境显示1)你想要打印的内容和2)评估表达式的返回值。例如
> (list (display 1))
1(#<void>)
打印“1”,然后打印列表结果。由于您在交互式会话中键入内容,因此始终会显示返回的值。您无法真正隐藏返回的值,但大多数方案将识别“未定义”返回值而不打印它。
> (display 1)
1
在上文中,即使display
返回#<void>
,解释器也知道不会显示它。