Coldfusion组件指针 [英] Coldfusion Component Pointers

查看:220
本文介绍了Coldfusion组件指针的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在构建一个Coldfusion组件的问题。好吧,我不确定是否是一个问题或事情是如何工作,但它似乎很奇怪。首先,我为我的组件的init函数设置参数,并调用该组件。但是如果我调用后更改其中一个参数,它还会更改组件中保存的值。这是正确的吗?



我不知道我是否解释得很好。这里有一些伪代码:

 < cfset fruit = [] /> 
< cfset fruit [1] = {
id = 1,
name =apple
} />
< cfset fruit [2] = {
id = 2,
name =orange
} />

< cfset args = {
title =Fruit,
data = fruit
} />

< cfinvoke component =testmethod =initreturnvariable =testargumentcollection =#args#/>

< cfset fruit [2] .name =banana/>

init 函数存储<$ c在组件的变量作用域中的$ c> title 和数据

现在,如果我从 test 对象中输出数据,我得到 apple banana 。但我期望组件保留在调用期间收到的数据。



让我知道如果我需要澄清什么。感谢任何帮助!

解决方案


我不确定这是一个问题还是应该是工作,


是的,这是当前的代码是如何工作的。



大多数复杂的对象(结构,组件,方程)都通过引用传递 >。意思是你基本上只是存储一个指向对象的指针,而不是实际的值。因此,您将始终看到对底层对象所做的任何更改。这就是为什么 test 的输出发生变化的原因。



数组是一个例外。它们通常(但不总是)通过值传递 。这意味着您有一个独立的副本,不会反映对原始对象所做的任何更改。



您的例子很有趣,因为它包含两者。对嵌套结构的更改( name = orange => name = banana )在组件中可见,通过引用。但是父数组不是。所以,你可以清除 fruit ,它对组件没有影响。



示例:

  cfset fruit [2] .name =bananna/> 

<!---两个转储将显示bananna--->
< cfdump var =#fruit#label =Fruit Before/>
< cfdump var =#test.getDataArray()#label =Test.Data Before/>

< cfset arrayClear(fruit)/>

<!--- fruit是空的,组件数组不是--->
< cfdump var =#fruit#label =Fruit After/>
< cfdump var =#test.getDataArray()#label =Test.Data After/>

测试

 < cfcomponent> 

< cffunction name =initreturntype =any...>
< cfargument name =titletype =stringrequired =true/>
< cfargument name =datatype =arrayrequired =true/>
< cfset variables.title = arguments.title />
< cfset variables.data = arguments.data />
< cfreturn this />
< / cffunction>

< cffunction name =getDataArrayreturntype =array>
< cfreturn variables.data />
< / cffonse>

< / cfcomponent>




现在,如果我从测试对象输出数据,苹果和香蕉。


右。这是预期的,因为结构通过引用传递。如果你想让组件维护一个独立的副本,你需要 duplicate()(即深复制) data 元素 init()

 < cfset variables.data = duplicate(arguments.data)/> 


I'm having an issue with a Coldfusion component that I'm building. Well, I'm not really sure if it's a problem or how things are supposed work, but it seems strange. First, I set up arguments for the init function of my component and invoke the component. But if I change one of the arguments after I invoke, it also changes the values held in the component. Is this correct?

I'm not sure if I'm explaining this very well. Here's some pseudo-code:

<cfset fruit = [] />
<cfset fruit[1] = {
    id = 1,
    name = "apple"
} />
<cfset fruit[2] = {
    id = 2,
    name = "orange"
} />

<cfset args = {
    title = "Fruit",
    data = fruit
} />

<cfinvoke component="test" method="init" returnvariable="test" argumentcollection=#args# />

<cfset fruit[2].name = "banana" />

The init function stores the title and data arguments in the component's variables scope.

Now, if I output the data from the test object, I get apple and banana. But I was expecting the component to retain the data that it received during the invoke.

Let me know if I need to clarify anything. Thanks for any help!

解决方案

I'm not really sure if it's a problem or how things are supposed work,

Yes, that is how your current code is supposed to work. Whether that is how you want it to behave is a different question ..

Most complex objects (structures, components, etectera) are passed by reference. Meaning you are essentially just storing a pointer to the object, not the actual values. So you will always see any changes made to the underlying object. That is why the output from test changes.

Arrays are an exception. They are usually (though not always) passed by value. Meaning you have an independent copy that will not reflect any changes made to the original object.

Your example is interesting because it contains both. Changes to your nested structures (name=orange => name=banana) are visible in the component because the structures are passed by reference. But the parent array is not. So you could clear fruit and it would have no effect on the component.

Example:

<cfset fruit[2].name = "bananna" />

<!--- both dumps will show "bananna" --->
<cfdump var="#fruit#" label="Fruit Before" />
<cfdump var="#test.getDataArray()#" label="Test.Data Before" />

<cfset arrayClear(fruit) />

<!--- fruit is empty and the component array is not --->
<cfdump var="#fruit#" label="Fruit After" /> 
<cfdump var="#test.getDataArray()#" label="Test.Data After" /> 

Test:

<cfcomponent>

  <cffunction name="init" returntype="any" ...>
     <cfargument name="title" type="string" required="true" />
     <cfargument name="data" type="array" required="true" />
     <cfset variables.title = arguments.title />
     <cfset variables.data = arguments.data />
     <cfreturn this />   
  </cffunction>

  <cffunction name="getDataArray" returntype="array">
     <cfreturn variables.data />
  </cffunction>

</cfcomponent>

Now, if I output the data from the test object, I get apple and banana.

Right. That is to be expected because structures are passed by reference. If you want the component to maintain a independent copy, you need to duplicate() (ie deep copy) the data element inside init().

   <cfset variables.data = duplicate(arguments.data) />

这篇关于Coldfusion组件指针的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆