在ColdFusion中如何在调用函数时仅指定一些可选参数?

18

我有一个ColdFusion函数"foo",它需要三个参数,其中后两个是可选的:

<cffunction name="foo" access="public" returntype="any">
    <cfargument name="arg1" type="any" required="true" />
    <cfargument name="arg2" type="any" required="false" default="arg2" />
    <cfargument name="arg3" type="any" required="false" default="arg3" />

    ...

    <cfreturn whatever />
</cffunction>

我想调用foo函数,传递参数arg1和arg3,但省略arg2。 我知道如果使用cfinvoke调用函数是可能的,但这种语法非常冗长和复杂。 我尝试了这两种方法,但都不起作用:

<cfset somevar=foo(1, arg3=3) /> <!--- gives syntax error --->
<cfset somevar=foo(1, arg3:3) /> <!--- gives syntax error --->
4个回答

33

您需要始终使用命名参数。不能像其他一些语言中那样混用命名参数和位置参数。

<cfset somevar = foo(arg1=1, arg3=3) />   

21

或者... 你可以使用 ArgumentCollection(参数集合)

在CF9或更高版本中...

<cfset somevar = foo(argumentCollection={arg1=1, arg3=3})>

In CF8 or above...

<cfset args = {arg1=1, arg3=3}>
<cfset somevar = foo(argumentCollection=args)>

If CF7 or below...

<cfset args = structNew()>
<cfset args.arg1 = 1>
<cfset args.arg3 = 3>
<cfset somevar = foo(argumentCollection=args)>

这是我通常的做法。我很可能在运行时确定要包含哪些参数。在<cfif>块中包装<cfset args.foo=bar>非常简单易懂。 - ale
1
正如Al所暗示的那样,您应该更新您的示例以显示ArgumentCollection的一个主要优点是它允许您以灵活的方式构建/操作结构体,然后再将其发送到函数 - 您当前的示例只是使用所有命名参数的冗长方式。 :) - Peter Boughton
1
值得注意的是,您可以在单个函数调用中混合使用命名参数和ArgumentCollection。 - Peter Boughton

2

如果您使用命名参数,则必须为第一个参数指定名称。

<cffunction name="foo" access="public" returntype="any">
    <cfargument name="arg1" type="any" required="true" />
    <cfargument name="arg2" type="any" required="false" default="arg2" />
    <cfargument name="arg3" type="any" required="false" default="arg3" />

    <cfreturn arg2 & " " & arg3>
</cffunction>


<cfset b = foo(arg1:1,arg3:2)>
<cfoutput>#b#</cfoutput>

0

和 Kip 一样,我也在寻找答案。下面是我实现的方式,希望能对我们可能的解决方案有所帮助。我只是在 cffunction 代码中添加了 <cfparam>

<cffunction name="fn1" access="public" returntype="numeric">
   <cfargument name="arg1" type="numeric" required="true">
   <cfargument name="arg2" type="numeric" required="true">
   <cfargument name="arg3" type="query" required="false">
   <cfparam name="arguments.arg1" default=0>
   <cfparam name="arguments.arg2" default=0>
   <cfparam name="arguments.arg3" default=0>
   <cfreturn arguments.arg1 + arguments.arg2 + arguments.arg3>
</cffunction>

<cfoutput>#fn1(arg1=1,arg2=2)#</cfoutput>

我认为这不会行,因为 <cfparam> 旨在“测试参数(即变量)的存在性,验证其数据,并且如果未分配默认值,则可以选择提供一个。” 在这种情况下,您将它们标记为必需,因此当执行到 cfparams 时,可以保证参数1至3已存在。(如果没有,函数调用将引发错误。)您可以在参数中提供默认值并使其非必需,但我猜测在这种情况下,这正是您想避免的。 - bean5

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接