【问题标题】:What is the difference between using "setq" or not to set an Emacs setting?使用“setq”或不设置 Emacs 设置有什么区别?
【发布时间】:2015-07-14 23:35:34
【问题描述】:

非常简单的问题,但让我困惑了一段时间:

(setq visible-bell t)

(visible-bell t)

两者似乎都有效。

但是

(desktop-save-mode 1)

工作,而

(setq desktop-save-mode 1)

不是。

请问这是为什么?

【问题讨论】:

    标签: emacs dot-emacs


    【解决方案1】:

    它们不同是因为它们不同:)

    (setq visible-bell t)
    

    正在将值 t 分配给名为 visible-bell变量

    (visible-bell t)
    

    正在调用一个名为visible-bell 的函数1(并将值t 作为参数传递)。

    (虽然仅供参考,在当前版本的 Emacs 中默认没有 visible-bell 函数,所以对我来说这并不明显实际上按照你的想法工作?但是,暂时假设你确实有这样的功能……)

    Emacs Lisp 是一个“Lisp-2”,这意味着它为变量和函数提供了单独的命名空间,因此您可以——并且通常会——拥有同名的变量和函数。引用哪一个总是隐含在代码的上下文中(例如,setq 总是引用一个变量)。

    简而言之,这两段代码在做非常不同的事情。这并不意味着它们不能具有等效的效果(例如,函数可能只是简单地设置变量的值);但是否真的如此,完全取决于函数的定义。


    1 事实上第一行代码调用了一个函数2:它调用setq并传递两个参数@ 987654330@ 和tsetq 然后根据其参数设置值。希望您现在开始了解 lisp 语法的工作原理?

    2 严格来说setq实际上是一种“特殊形式”而不是函数,特殊形式更接近于宏而不是函数;但这些区别对于本次问答并不重要。

    【讨论】:

    • 抱歉,评论有点晚了。最后获得足够的声望点击“向上”按钮。谢谢。
    【解决方案2】:

    其他人已经告诉你关于 setq 所做的事情以及关于变量与函数的基本观点。

    visible-bell 本身:

    1. 没有功能 visible-bell 随 Emacs 一起提供,在我所知道的任何 Emacs 版本中,而且从来没有。 (我已经通过 Emacs 20 进行了检查,凭记忆我相信从一开始也是如此。只有 变量 visible-bell

      正如@phils 所建议的,不清楚你所说的是真的:“似乎都有效”。除非您正在加载的一些额外代码定义了该名称的函数(然后我们无法评论它,没有看到它),评估(visible-bell t) 会引发未定义(无效)函数错误。

    2. 变量visible-bell 不仅仅是一个变量。这是一个用户选项,而且至少从 Emacs 20 开始就是这样。

    3. 您应该,一般来说,只需使用setq 来更改用户选项的值。在很多情况下,这样做不会惹上麻烦,但有时会惹上麻烦,而且这不是一个好习惯。

      setq 不执行任何可能适合给定用户选项的特殊初始化或更新操作。它不适用于用户选项。或者更确切地说,用户选项不适用于 setq - 它们可能比 setq 提供的更复杂。

    4. 应该使用什么来代替setq自定义。以交互方式(M-x customize-option RET visible-bell RET,或C-h v RET visible-bell RET,然后单击customize 链接)或在初始化文件中使用 Lisp 代码。

    5. 如果您使用 Lisp 代码,请使用以下函数之一(不是 setq):

      • customize-set-variable
      • customize-set-value
      • custom-set-variables

      使用C-h f 后跟每个函数名称,看看有什么(细微的)差异。

    【讨论】:

    • 抱歉,评论有点晚了。最后获得足够的声望点击“向上”按钮。谢谢。
    【解决方案3】:

    这里有 3 个问题。

    1. 在 Emacs Lisp 中,同一个符号既可以是变量也可以是函数。

    在桌面保存模式的情况下,它是一个函数,也是一个变量。

    因为是函数,所以可以调用

    (desktop-save-mode 1)
    

    因为它是一个变量,所以你给它赋值

    (setq desktop-save-mode t)
    

    你可以定义自己的函数,也可以定义一个同名的变量来测试它。

    注意:函数的参数应该是什么或变量的值是什么有意义取决于函数或变量。

    1. 现在,第二期。一般来说,对于激活次要模式的函数(命令),约定是正整数应该表示打开,否则关闭。

    此外,对于激活次要模式的命令,通常有一个同名的变量,其值为 t 或 nil,以指示该模式是否开启。

    1. 现在,有第三期。对于激活模式的命令,在 emacs 24 左右之前,按照惯例,如果没有给出 arg,则命令切换当前状态。

    由于以上所有因素,这个问题令人困惑。您可能会在 init 中看到如下内容:

    (desktop-save-mode 1) ; correct. To turn on.
    (desktop-save-mode) ; Confusing. Should take value 1 to turn on. Usually works because by default it's off.
    (desktop-save-mode t) ; wrong. Take value of positive integer to turn on.
    (desktop-save-mode nil) ; Confusing. Value should be integer
    (setq desktop-save-mode t) ; wrong. Shoud call function instead
    (setq desktop-save-mode nil) ; wrong. Shoud call function instead
    (setq desktop-save-mode 1) ; wrong. Shoud call function instead. Besides, only t and nil make sense
    

    所以,有很多混乱。在 emacs 24(或 23.x)中,约定发生了变化,因此,如果它没有收到任何值,它将打开,如果在 elisp 代码中调用。 (当作为命令交互调用时,它会切换。)

    最后,总是调用 describe-function 或 describe-variable 来读取文档。

    【讨论】:

      【解决方案4】:

      setq(它是具有自动引用功能的“设置”)用于为变量赋值。在此示例中,显然不需要,因为正如您所提到的,省略它适用于第一组示例。

      基本上,可见钟是一个变量,您可以将值“t”分配给它以启用可见铃。

      但是,桌面保存模式是一个交互功能,所以你不用 setq 给它赋值,你用参数调用它。

      当您不确定某事是什么时,要做的一件好事是使用内置帮助功能:

      C-h v visible-bell RET
      

      这将返回可见铃的信息——注意命令中的“v”是因为它是一个变量。如果你想搜索一个函数的信息,你可以这样做:

      C-h f desktop-save-mode RET
      

      顺便说一下,在这种情况下,桌面保存模式也是一个变量,但它是一个只读变量,用于确定是否启用桌面保存模式,因此尝试更改它是行不通的。

      【讨论】:

        猜你喜欢
        • 2013-08-12
        • 1970-01-01
        • 2020-08-14
        • 1970-01-01
        • 2018-05-08
        • 2011-08-04
        • 1970-01-01
        • 2012-02-14
        • 2011-12-19
        相关资源
        最近更新 更多