为啥 Octave 不将变量封装在嵌套函数中?

Posted

技术标签:

【中文标题】为啥 Octave 不将变量封装在嵌套函数中?【英文标题】:Why does Octave not encapsule variables inside of nested functions?为什么 Octave 不将变量封装在嵌套函数中? 【发布时间】:2021-12-22 01:38:49 【问题描述】:

在 Octave 中编写嵌套函数时,变量似乎没有被封装:

function r = asd()
    fn1();
endfunction

function res1 = fn1()
    res1 = 0;
    function res2 = fn2()
        res2 = 0;
        for i = 10:20
            res2 = res2 + i;
        endfor
    endfunction
    for i = 1:10
        printf("i before calling fn2(): %d\n", i);
        res1 = res1 + fn2();
        printf("i after calling fn2(): %d\n", i);
    endfor
endfunction

这对我来说似乎很奇怪,因为它尖叫着寻找错误,对吧?这里没有封装变量是否有特定原因?

【问题讨论】:

我同意。公平地说,嵌套函数一开始有点奇怪,我一般只是不使用它们。只是让它们成为一个函数,而不是嵌套 除了下面 Cris 的回答之外,这里还有关于嵌套函数的 octave 文档页面:octave.org/doc/v6.4.0/Nested-Functions.html。正如 Cris 所暗示的,嵌套函数是 Matlab/Octave 创建closures 的方式。否则,在大多数其他情况下,应该首选普通的subfunctions,并将所需的变量显式传递给子函数以保持封装,正如您正确建议的那样。 【参考方案1】:

嵌套函数显式存在以与封闭函数共享变量。这是他们的目的。如果您不希望私有函数与调用函数共享变量,请将其声明在同一 M 文件中的调用函数之后。这使它成为一个“本地函数”,一个仅在该文件中可见的函数。

通常嵌套函数很奇怪,应该只在特定情况下使用。它们有用的一个地方是将变量封装在比匿名函数更复杂的 lambda 中:

% Returns a function that depends on x
function f = createLambda(x)
   y = atan(x); % some calculation
   function res = nested(val)
      res = y * val; % …but this would be several lines or a loop or whatever
   end
   f = @nested
end

Octave 中存在嵌套函数,因为它们是在 MATLAB 中引入的。您应该阅读the excellent MATLAB documentation 以了解有关它们的更多信息。

【讨论】:

以上是关于为啥 Octave 不将变量封装在嵌套函数中?的主要内容,如果未能解决你的问题,请参考以下文章

为啥嵌套函数可以从外部函数访问变量,但不允许修改它们[重复]

js代码嵌套问题,为啥外层定义的变量内层不能使用

C语言中函数为啥可以嵌套定义 ?

为啥在 BigQuery 中取消嵌套两个或多个变量时没有得到任何结果?

面向对象---成员,嵌套(建模)

为啥嵌套函数不会成为javascript中外部函数的属性?