Как указать только некоторые необязательные аргументы при вызове функции в ColdFusion?

У меня есть функция 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 --->

person Kip    schedule 01.07.2009    source источник


Ответы (4)


Вы должны использовать именованные аргументы повсюду. Вы не можете смешивать именованные и позиционные аргументы, как в некоторых других языках.

<cfset somevar = foo(arg1=1, arg3=3) />   
person Patrick McElhaney    schedule 01.07.2009

Или... вы можете использовать ArgumentCollection

В CF9 или выше...

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

В CF8 или выше...

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

Если CF7 или ниже...

<cfset args = structNew()>
<cfset args.arg1 = 1>
<cfset args.arg3 = 3>
<cfset somevar = foo(argumentCollection=args)>
person Henry    schedule 01.07.2009
comment
Я обычно так и предпочитаю делать. Я, скорее всего, определяю, какие аргументы включить во время выполнения. Удобно и легко поместить ‹cfset args.foo=bar› в блок ‹cfif›. - person ale; 02.07.2009
comment
Как подразумевает Al, вы должны обновить свои примеры, чтобы показать, что основное преимущество ArgumentCollection заключается в том, что он позволяет вам создавать/манипулировать структурами гибким образом, прежде чем отправлять их в функцию - ваши текущие примеры просто многословны. использования всех именованных аргументов. :) - person Peter Boughton; 05.07.2009
comment
Также стоит отметить, что вы можете смешивать и сопоставлять именованные аргументы и ArgumentCollection в одном вызове функции. - person Peter Boughton; 05.07.2009

если вы используете именованные аргументы, вы также должны назвать первый

<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>
person Nick Van Brunt    schedule 01.07.2009

Я тоже искал ответы, как написал Кип. Вот что я реализовал. Надеюсь, это может добавить к нашей цепочке возможных решений. Я просто добавил <cfparam> в код cffunction:

<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>
person Ananthakrishnan    schedule 28.07.2011
comment
Я не думаю, что это сработает, поскольку <cfparam> предназначен для проверки существования параметра (то есть переменной), проверки его данных и, если значение по умолчанию не назначено, необязательно предоставляет его. В этом случае вы помечаете их по мере необходимости, поэтому к моменту обращения к параметрам cfparams вам гарантируется, что аргументы 1-3 существуют. (Если бы они этого не сделали, вызов функции выдал бы ошибку.) Вы могли бы указать значение по умолчанию в аргументе и сделать его необязательным, но я предполагаю, что в этом контексте вы пытаетесь избежать именно этого. - person bean5; 24.10.2013