【问题标题】:Why are local variables variable is not respected?为什么局部变量变量不被尊重?
【发布时间】:2010-07-31 13:29:33
【问题描述】:

在这段代码sn-p中,fields-types最后被to-camel-case函数修改,而不是作为局部变量传递给父函数:

fields-types: ["First Name" "string" "Last Name" "string" "Age" "int"]

to-camel-case: function [name] [
    name/1: lowercase name/1
    replace/all name space ""
]

fill-template-body: func [
    field-labels-types [block!] /local vars fields-names-types
] [
  vars: [member-name member-type]
  field-names-types: copy []
  foreach [field-label field-type] field-labels-types [
      append field-names-types to-camel-case field-label
      append field-names-types field-type
  ]
]

fill-template-body fields-types

执行给出:

>> fill-template-body fields-types
== ["firstName" "string" "lastName" "string" "age" "int"]
>> fields-types
== ["firstName" "string" "lastName" "string" "age" "int"]
>>

而我希望字段类型保持不变:

fields-types: ["First Name" "string" "Last Name" "string" "Age" "int"]

当然,我可以尝试通过修改 to-camel-case 以使用名称副本来规避这一点,但我认为我不应该这样做。

Scala 中有类似 varval 关键字的东西吗?

【问题讨论】:

    标签: scope rebol rebol3


    【解决方案1】:

    变量在 REBOL 中是一个丑陋的词,一切——甚至是词——都是值。这不是什么语义新闻,它有助于理解 REBOL 的流动方式。

    我认为值包含在内存中的一个巨大数组中,其中 REBOL(语言)使用单词及其上下文来引用值并与之交互。大多数 REBOL 函数在不重复这些值的情况下运行:

    head lowercase next uppercase str: "abcd"
    remove back tail str
    

    这是 REBOL 最有效的功能之一 - 您不需要 中间过程的副本,要求这样是浪费。想想每次使用replaceuppercaseto-camel-case 时都会重复一个值的数组。整个过程可以在修改而不是重复的前提下构建——实际上可以构建上下文而不必返回值:

    remove-spaces: use [space mark][
        space: charset " ^-"
        [any [mark: space (remove mark) | skip]]
    ]
    
    parse/all str: "Should Be No Spaces" remove-spaces
    

    然后诀窍就是知道在哪里复制值,我认为恰好与 REBOL 的简洁表达天赋相交:

    parse/all link: copy title: "An Article on REBOL" remove-spaces
    print ["(" link ")" title]
    
    to-camel-case copy field-label
    

    当然,修改也有其局限性。有时从头开始构建更清洁。

    【讨论】:

    • 感谢会重读几次。仍然有一种机制可以提供选择,可能是 val 关键字reboltutorial.com/blog/scala-val-keyword 之类的东西?将不得不考虑它。
    • 在我看来你想'保护一个值,而不是一个单词(?)这在 REBOL 中不会发生: foo: bar: "foobar"protect 'foo 大写 bar probe foo 保护一个单词只会阻止您将其分配给另一个值。值本身仍然可以通过另一个引用进行操作,除非您使用副本。 bar: copy foo: "foobar" protect 'foo 大写 bar probe foo
    • 我同意 cmets 和换行符 :)
    • 我想要的是本地经典行为,当我需要它时,我希望某种标志或关键字不是每次都这样做,因为我喜欢 rebol 不强制局部性但有时当我决定。我希望自己决定自己的选择,而不是强加给我的语言。
    【解决方案2】:

    您的驼峰式函数对原始值进行操作,因此如果您想保留原始值,您需要复制它并返回更改后的值。由于您的函数作用于模板,因此需要复制模板对吗??

    所以,这样的事情应该可以工作:

    fill-template-body: func[ labels [block!] /local field-labels-types vars fields-names-types][
      field-labels-types: copy labels
    ..
    

    【讨论】:

    • 是的,这就是我所做的,但我只是说应该有一个自动机制,比如 scala 中的 val 关键字,这样就不必每次都考虑它了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-04-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-24
    • 2021-05-21
    • 2020-01-15
    相关资源
    最近更新 更多