处理多个可选参数
Dealing with more than one Optional parameter
我有程序
f:=proc(x,option1,option2) ... end proc;
在我的例子中,option1
总是一个整数,option2
是一个列表或其他东西(包括整数)。这两个选项都是可选的,因此这些命令按预期工作:
f(x);
f(x,3);
f(x,4,[1,2]);
f(x,5,3);
f(x,6,expand);
但是如果没有指定 option1
那么我不知道一个简单的方法来处理它,因为 Maple 不允许像
这样的用法
f(x,,3);
f(x,,[1,2]);
我可以让它明白
f(x,[1,2]);
但我还是有问题
f(x,3);
因为不清楚 3
是 option1
还是 option2
。我可以重写代码来理解这种格式的函数调用
f(x,[1,option1],[2,option2]);
f(x,[1,option1]);
f(x,[2,option2]);
但我很好奇是否有更简单的方法来实现这一点,因为对于某些 Maple 函数(如 plot
),大多数选项的顺序无关紧要。
使用关键字参数。
f:=proc(x,{op1::integer:=0,op2::{list,integer}:={}},$)
if has([_passed],'op1') then
print("op1 =",op1);
else
print("op1 not passed");
fi;
if has([_passed],'op2') then
print("op2 =",op2);
else
print("op2 not passed");
fi;
#rest of code
end proc;
现在你可以做
f(x,'op2'=[1,2,3])
"op1 not passed"
"op2 =", [1, 2, 3]
和
f(x,'op1'=99)
"op1 =", 99
"op2 not passed"
和
f(x)
"op1 not passed"
"op2 not passed"
和
f(x,'op1'=99,'op2'=[1,2,3])
"op1 =", 99
"op2 =", [1, 2, 3]
和
f(x,'op1'=99,'op2'=19827)
"op1 =", 99
"op2 =", 19827
确保调用时使用'op1'=value
,而不是op1=value
大多数绘图命令使用 Maple 的更现代的 argument-processing 来管理程序选项。
特别是大多数绘图命令选项都作为 so-called keyword 选项提供。这会自动提供(此类选项的)位置无关紧要的功能。
例如,
f:=proc(v,
{ord::{integer,NoUserValue}:=':-NoUserValue'},
{special::{integer,list,NoUserValue}:=':-NoUserValue'});
print(':-ord'=ord, ':-special'=special);
end proc:
f(x);
ord = NoUserValue, special = NoUserValue
f(x,ord=3);
ord = 3, special = NoUserValue
f(x,special=5);
ord = NoUserValue, special = 5
f(x,special=5,ord=3);
ord = 3, special = 5
f(x,ord=3,special=5);
ord = 3, special = 5
如您所见,您[逻辑上]不能使用多个 *positional/ordered" 参数,如果它们具有相同的类型并且缺少一些较早的参数。
如果您真的想要,可以将这些选项之一变成 positional parameter,尽管这自然会失去任意放置的灵活性。例如,
restart;
f2:=proc(v,
ord::{integer,NoUserValue}:=':-NoUserValue',
{special::{integer,list,NoUserValue}:=':-NoUserValue'});
print(':-ord'=ord, ':-special'=special);
end proc:
f2(x);
f2(x,3);
f2(x,special=5);
f2(x,special=5,3);
f2(x,3,special=5);
restart;
f3:=proc(v,
special::{integer,list,NoUserValue}:=':-NoUserValue',
{ord::{integer,NoUserValue}:=':-NoUserValue'});
print(':-ord'=ord, ':-special'=special);
end proc:
f3(x);
f3(x,5);
f3(x,ord=3);
f3(x,ord=3,5);
f3(x,5,ord=3);
变体太多,无法在此处一一展示。
您不必使用名称“NoUserValue”作为默认值。
正如其他人已经提到的,一种解决方案是使用“kwarg”(关键字参数)。您也可以使用 _passed
或 _rest
。您可以在 Maple 帮助页面或 Maple 编程指南 (https://www.maplesoft.com/documentation_center/Maple2021/ProgrammingGuide.pdf) 中阅读更多内容。
这只是您如何使用它们的示例。 _passed
用于当您想说出传递给您的过程的任何内容时,_rest
用于传递给您的过程的任何内容,除了已经分配给您在里面提到的参数的那些proc
前面的括号。假设我们要定义一个过程,其中包含 1 个必要参数和 2 个可能的可选参数。如果给出了两个可选参数,我们假设第一个总是option1
,第二个是option2
,但是如果只给出一个可选参数,那么取决于它是否是[=]类型18=] 或不是它分别是 option1
或 option2
。
要询问传递的参数数量或剩余的传递参数,您可以使用 _npassed
和 _nrest
。命令 assigned()
检查是否为某物分配了值。您可以通过 type(-,-)
或 - :: -
检查某物是否属于特定类型。所以这是简单的代码。
test := proc( x )
local option1, option2:
if _nrest = 2 then
option1 := _rest[1]:
option2 := _rest[2]:
elif _nrest = 1 then
if _rest[1] :: integer then
option1 := _rest[1]:
else
option2 := _rest[1]:
end if:
end if:
printf( "necessary argument is %a\n", x ):
if assigned( option1 ) then
printf( "option 1 is given and is %d\n", option1 ):
end if:
if assigned( option2 ) then
printf( "option 2 is given and is %a\n", option2 ):
end if:
end proc:
下面是上述程序针对不同输入的输出截图。
我有程序
f:=proc(x,option1,option2) ... end proc;
在我的例子中,option1
总是一个整数,option2
是一个列表或其他东西(包括整数)。这两个选项都是可选的,因此这些命令按预期工作:
f(x);
f(x,3);
f(x,4,[1,2]);
f(x,5,3);
f(x,6,expand);
但是如果没有指定 option1
那么我不知道一个简单的方法来处理它,因为 Maple 不允许像
f(x,,3);
f(x,,[1,2]);
我可以让它明白
f(x,[1,2]);
但我还是有问题
f(x,3);
因为不清楚 3
是 option1
还是 option2
。我可以重写代码来理解这种格式的函数调用
f(x,[1,option1],[2,option2]);
f(x,[1,option1]);
f(x,[2,option2]);
但我很好奇是否有更简单的方法来实现这一点,因为对于某些 Maple 函数(如 plot
),大多数选项的顺序无关紧要。
使用关键字参数。
f:=proc(x,{op1::integer:=0,op2::{list,integer}:={}},$)
if has([_passed],'op1') then
print("op1 =",op1);
else
print("op1 not passed");
fi;
if has([_passed],'op2') then
print("op2 =",op2);
else
print("op2 not passed");
fi;
#rest of code
end proc;
现在你可以做
f(x,'op2'=[1,2,3])
"op1 not passed"
"op2 =", [1, 2, 3]
和
f(x,'op1'=99)
"op1 =", 99
"op2 not passed"
和
f(x)
"op1 not passed"
"op2 not passed"
和
f(x,'op1'=99,'op2'=[1,2,3])
"op1 =", 99
"op2 =", [1, 2, 3]
和
f(x,'op1'=99,'op2'=19827)
"op1 =", 99
"op2 =", 19827
确保调用时使用'op1'=value
,而不是op1=value
大多数绘图命令使用 Maple 的更现代的 argument-processing 来管理程序选项。
特别是大多数绘图命令选项都作为 so-called keyword 选项提供。这会自动提供(此类选项的)位置无关紧要的功能。
例如,
f:=proc(v,
{ord::{integer,NoUserValue}:=':-NoUserValue'},
{special::{integer,list,NoUserValue}:=':-NoUserValue'});
print(':-ord'=ord, ':-special'=special);
end proc:
f(x);
ord = NoUserValue, special = NoUserValue
f(x,ord=3);
ord = 3, special = NoUserValue
f(x,special=5);
ord = NoUserValue, special = 5
f(x,special=5,ord=3);
ord = 3, special = 5
f(x,ord=3,special=5);
ord = 3, special = 5
如您所见,您[逻辑上]不能使用多个 *positional/ordered" 参数,如果它们具有相同的类型并且缺少一些较早的参数。
如果您真的想要,可以将这些选项之一变成 positional parameter,尽管这自然会失去任意放置的灵活性。例如,
restart;
f2:=proc(v,
ord::{integer,NoUserValue}:=':-NoUserValue',
{special::{integer,list,NoUserValue}:=':-NoUserValue'});
print(':-ord'=ord, ':-special'=special);
end proc:
f2(x);
f2(x,3);
f2(x,special=5);
f2(x,special=5,3);
f2(x,3,special=5);
restart;
f3:=proc(v,
special::{integer,list,NoUserValue}:=':-NoUserValue',
{ord::{integer,NoUserValue}:=':-NoUserValue'});
print(':-ord'=ord, ':-special'=special);
end proc:
f3(x);
f3(x,5);
f3(x,ord=3);
f3(x,ord=3,5);
f3(x,5,ord=3);
变体太多,无法在此处一一展示。
您不必使用名称“NoUserValue”作为默认值。
正如其他人已经提到的,一种解决方案是使用“kwarg”(关键字参数)。您也可以使用 _passed
或 _rest
。您可以在 Maple 帮助页面或 Maple 编程指南 (https://www.maplesoft.com/documentation_center/Maple2021/ProgrammingGuide.pdf) 中阅读更多内容。
这只是您如何使用它们的示例。 _passed
用于当您想说出传递给您的过程的任何内容时,_rest
用于传递给您的过程的任何内容,除了已经分配给您在里面提到的参数的那些proc
前面的括号。假设我们要定义一个过程,其中包含 1 个必要参数和 2 个可能的可选参数。如果给出了两个可选参数,我们假设第一个总是option1
,第二个是option2
,但是如果只给出一个可选参数,那么取决于它是否是[=]类型18=] 或不是它分别是 option1
或 option2
。
要询问传递的参数数量或剩余的传递参数,您可以使用 _npassed
和 _nrest
。命令 assigned()
检查是否为某物分配了值。您可以通过 type(-,-)
或 - :: -
检查某物是否属于特定类型。所以这是简单的代码。
test := proc( x )
local option1, option2:
if _nrest = 2 then
option1 := _rest[1]:
option2 := _rest[2]:
elif _nrest = 1 then
if _rest[1] :: integer then
option1 := _rest[1]:
else
option2 := _rest[1]:
end if:
end if:
printf( "necessary argument is %a\n", x ):
if assigned( option1 ) then
printf( "option 1 is given and is %d\n", option1 ):
end if:
if assigned( option2 ) then
printf( "option 2 is given and is %a\n", option2 ):
end if:
end proc:
下面是上述程序针对不同输入的输出截图。