不使用“copy”处理字符串时究竟发生了什么?

时间:2013-08-09 07:07:32

标签: rebol rebol3

下面这个函数的目的是返回一个在两个星之间插入参数值的字符串。

star-name: func [name /local stars] [
    stars: "**"
    insert next stars name
    stars
]
print star-name "test" ;*test*
print star-name "this" ;*thistest*, but what I really want is *this*  

第二次调用该函数时,第一次调用的参数仍然插入。我知道答案是使用copy "**"。 我的问题是,每次调用函数时,它都不会将stars变量重新分配给"**"吗?

2 个答案:

答案 0 :(得分:6)

在函数的情况下,只有一个“**”字符串定义。 Rebol load函数只使用该定义一次,因为load仅运行一次以将代码转换为Rebol内部形式 - 一个块。确实,如果你调用函数两次,赋值会发生两次,但是赋值不会创建任何东西,只是让变量再次引用相同的字符串。

在你的评论中你应该注意到你实际上有两个“**”字符串定义,导致load创建了两个字符串。如果你使用

code: [stars: "**" insert next stars something]
something: "this"
do code
something: "that"
do code

您会注意到只有一个字符串定义,而您没有任何功能时,其行为与使用函数时的行为相同。

答案 1 :(得分:2)

如果在系列中使用set-word,则默认行为是仅为该系列分配一次内存。这允许您将其用作在您找到的函数调用之间保持的静态变量。

如果您不想要这种行为,那么您需要明确复制该系列以每次创建一个新系列。

这是另一种方法,因为不需要本地星星

star-name: func [ name ][
  rejoin [ "*" name "*" ]
]