如果我有
<cfset arr_arguments = ["a","b","c"]>
<cfunction name="someFunction">
<cfargument name="someArgumentOne">
<cfargument name="someArgumentTwo">
<cfargument name="someArgumentThree">
</cffunction>
有没有办法使用someFunction
参数调用arr_arguments
,类似于someFunction("a","b","c")
?我当然知道我可以使用argumentCollection
将(键控)结构传递给函数,但我特别询问传入(无键)数组。在JS中,可以使用someFunction.apply(this,arr_arguments)
轻松完成,但在coldfusion中,我无法找到任何方法。
答案 0 :(得分:4)
未命名的参数作为结构传递给函数,其数字键与函数参数中定义的参数的位置相匹配。因此,您可以将数组转换为带有数字键的结构,然后使用argumentCollection传递结构,而不是传递命名参数:
<cfset arr_arguments = {"1"="a","2"="b","3"="c"}>
<cfset someFunction(argumentCollection=arr_arguments)>
您可以使用如下数字键轻松地将数组转换为结构:
<cfset args = {}>
<cfloop from="1" to="#arrayLen(arr_arguments)#" index="i">
<cfset args[i] = arr_arguments[i]>
</cfloop>
答案 1 :(得分:2)
在Coldfusion 10中,您可以使用invoke function来执行此操作。它似乎是一种无法按顺序传递参数数组的方法。 cfscript中的示例:
invoke('', 'someFunction', ['a','b','c']);
invoke
的第一个参数是组件名称(或UDF的空字符串)。第二个是函数名,第三个是参数数组。请注意,组件和函数名称必须作为字符串传递。
我测试了这个有和没有定义的参数名称,并保留了参数的顺序。
答案 2 :(得分:1)
好的,如果你想调用带有任意参数数组的函数,我建议的最佳选择就是创建一个包装函数。见下面的示例代码
<cfscript>
function testMe(
required string arg1,
required string arg2
) {
writedump(arguments);
}
function invokeFunction(
required inFunction,
required array functionArguments
) {
var stcArguments = {};
// Introspect to get the method parameters
var arrFunctionArguments = GetMetaData(arguments.inFunction).parameters;
// Now figure out what we are iterating to
var numArgumentsToParse = Min(ArrayLen(arguments.functionArguments),ArrayLen(arrFunctionArguments));
// Populate the arguments structure
for (var i=1;i<=numArgumentsToParse;i++) {
stcArguments[arrFunctionArguments[i].name] = arguments.functionArguments[i];
}
// And try to call it
return arguments.inFunction(
argumentCollection = stcArguments
);
}
invokeFunction(testMe,[1,2]); // Works fine
invokeFunction(testMe,[1,2,3,4]); // Just skips 3 and 4
// invokeFunction(testMe,[1]); // Errors due to not enough arguments
// invokeFunction(fakeFunctionName,[1]); // Errors due to undefined function
</cfscript>
如果发生以下任何一种情况,这当然会出错
但你可以在外面处理。这将使用内省来计算参数名称,相应地填充结构,并调用所请求的函数。
答案 3 :(得分:1)
这是一个UDF,它将为您做到这一点:
<cfscript>
function test_function(a,b,c){
writeOutput("arguments.a"&arguments.a&"<br>");
writeOutput("arguments.b"&arguments.b&"<br>");
writeOutput("arguments.c"&arguments.c&"<br>");
return arguments.a & "::" & arguments.b & "::" & arguments.c;
}
function invoke_positional(func,arr){
var metaData = GetMetaData(func);
var args={};
for(var pos=1;pos<=ArrayLen(arr);pos++){
args[metaData.parameters[pos].name]=arr[pos];
}
return arguments.func(argumentCollection=args);
}
data = ["StringOne","StringTwo",22];
result = invoke_positional(test_function,data);
</cfscript>
<cfoutput>
<p>
Returned: #result#
</p>
</cfoutput>
invoke_positional通过使用UDF的元数据来构建一组命名参数,然后将它们与argumentCollection =
一起使用答案 4 :(得分:0)
因此,我发现有一个选项是与实际的实参数范围分开创建一个参数对象,只需使用数字索引将值添加到它。
<cfset args_input = createObject("java","com.naryx.tagfusion.cfm.engine.cfArgStructData").init()>
<cfloop from="1" to="#arraylen(arr_arguments)#" index="i">
<cfset args_input[i] = arr_arguments[i]>
</cfloop>
<cfset someFunction(argumentCollection=args_input)>
如果您使用adobe coldfusion遇到这种情况,我会建议您尝试
<cfset correctClass = arguments.getClass().getName()>
要将字符串传递给createObject。或者,如果这不起作用,只需要一个专用函数来返回一个空参数对象
<cfset args_input = this.generateArgumentObject()>
和
<cffunction name="generateArgumentObject">
<cfreturn arguments>
</cffunction>
哦,我确切知道的是,它肯定会在OpenBD中运行,并且基于我过去在Ben Nadel的博客上看到的帖子,我很确定这也应该适用于Adobe ColdFusion。