使用带有可选输入参数的函数

Using a function with optional inputted parameters

我已经为这个问题苦苦挣扎了大约一个星期。我一直在尝试将脚本转换为用于研究目的的函数。问题是代码有很多变量的条件现有语句,因此某些变量在检查时不会存在于工作区中(这就是它作为脚本运行良好的原因)。

Varargin 不是解决此问题的方法,因为某些函数 INPUTS 将不存在。

工作空间

var1 = 1
var2 = 2
var4 = 4

转成函数的代码

if exist('var3','var')
   disp('var 3 exists')
else
   disp('var 3 does not exist')
end

以下函数将无法运行,因为它正在调用不存在的变量 3。

调用函数

runCode(var1, var2, var3, var4)

我最初是在我的函数之前写的,并检查了 isnan 而不是 exist 的代码,但这不是很好的做法,而且由于经常调用该函数,我不想每当更改代码时都必须更新此功能设置。

  if ~exist("var1", "var"), var1= NaN; end 
  if ~exist("var2", "var"), var2= NaN; end 
  if ~exist("var3", "var"), var3= NaN; end 
  if ~exist("var4", "var"), var4= NaN; end 

我不想使用 eval,并且加载工作区给我带来了问题,因为出现了一堆图形,并且在代码的后面部分弄乱了图形计数。我唯一知道的想法是为前面的 if 语句设置脚本,或者以某种方式将所有工作区数据保存到结构或其他内容中,然后将值分配给相应的 who 字符串(给出工作区变量名称) .

感谢你们的任何想法

您可以将输入设为 arg 对,这样您就可以这样称呼它:

runCode ( 'var1', 123, 'var2', 456, 'var4', 789)

你的功能在哪里

function runCode ( varargin )
  defaults.var1 =[];
  defaults.var2 =[];
  defaults.var3 =[];
  defaults.var4 =[];

  for ii = 1:2:nargin
    if isfield ( defaults, varargin{ii} )
      defaults.(varargin{ii}) = varargin{ii+1};
    else
      Throw error?
    end

然后您更改对 var3 的检查以检查值 defaults.var3 是否为空。

当前脚本的行为有所不同,具体取决于是否存在一组具有预定义名称的变量。这很难在函数中复制,因为函数 不应 不读取调用工作区的值。这当然是可以做到的:

try
   var1 = evalin('caller','var1');
catch
   % do nothing, the variable doesn't exist in the caller, it won't exist here
end

但这确实不好的做法,和脚本没什么区别。 OP 明确表示不想使用 eval.

有一个替代方案,我犹豫要不要推荐它,因为它几乎和上面的一样邪恶。我们将定义一个函数,其输入参数不是基于顺序,而是基于名称:

runCode(var1)

行为将不同于

runCode(var2)

但以下两个语句的行为相同:

runCode(var1,var2)
runCode(var2,var1)

歪了?你应该是!

诀窍是使用 inputname 如下:

function runCode(varargin)
for ii = 1:nargin
   switch inputname(ii)
      case 'var1', var1 = varargin{ii};
      case 'var2', var2 = varargin{ii};
      case 'var3', var3 = varargin{ii};
      case 'var4', var4 = varargin{ii};
      otherwise,   error('Illegal input argument')
   end
end

函数的其余部分将是 OP 脚本的主体,其中包含如下代码:

if exist('var1','var')
   % ...
end

也就是先看有哪些变量传给了函数,再看有哪些变量存在。应该可以重写脚本本身,用查找输入参数名称列表来替换 exist 检查。

感谢所有反馈。由于我想调用的函数有时是从同一个地方调用的,但存在不同的变量,所以我无法改变参数的设置方式。所以,我所做的可能会让你们哭泣,但我有一个设置脚本,我在函数之前调用它来检查参数是否存在,如果不存在则将它们设置为 NaN。它与我之前使用的完全相同的解决方案,但在脚本中。

PS 我同意这应该保留为脚本,但他们真的希望它成为一个函数¯_(ツ)_/¯