2

当在任何类型的循环中使用任何类型的条件时,我一直在努力解决最奇怪的错误。

我不断收到的错误是:“复杂对象类型无法转换为简单值。” 在包含<cfloop condition="true">. 更有趣的是 a<cfbreak>并没有跳出循环。我已使用 Eclipse 中的调试器来确认此代码是否已实际执行。

奇怪的是,有时代码会永远循环,即使我知道它<cfbreak>会被执行,有时它会在第一次迭代时出错。

我已确认此问题也发生在另外两台计算机上。

在每个人都对我使用永远为真条件感到抓狂之前,我曾经有一个有效条件:<cfloop condition="not done"> where done 是一个布尔值。这导致了同样的错误。

我正在处理其他人编写的旧代码,因此目前无法选择重写。

我刚刚将 ColdFusion 8.0.1 修补到最新的更新程序 4 以查看是否可以解决问题,但它没有。

这就是代码本质上的样子:

<cfloop condition="true">
    <cfif condition is true>
        <cfbreak>
    </cfif>
</cfloop>

这是执行的代码:

<cfset done = false />
<cfloop condition="true">
    <cfscript>
        try
        {
            lineitem.quantity = quantityRemaining;

            quantityRemaining = 0;

            arrayAppend( currentTub, lineitem );

            currentCartItemCount = currentCartItemCount + lineitem.quantity;
            currentTubItemCount = currentTubItemCount + lineitem.quantity;

        }
        catch(Any e){}


        availableSpaceInCart = this.itemsPerCart - currentCartItemCount;
        availableSpaceInTub = this.itemsPerTub - currentTubItemCount;
    </cfscript>

    <cfif quantityRemaining LTE 0>
        <cfset done = true />
        <cfbreak />
    </cfif>
</cfloop>

更新:

好吧,我们弄清楚了问题所在。<CFOUTPUT>这个循环周围有两个标签,外部<CFOUTPUT query='query_name' groupby='column_name'>标签使用的是QueryNew()生成的查询,出于某种原因,ColdFusion 不喜欢它。所以我们解决了这个问题,它解决了我们奇怪的问题。

4

4 回答 4

2

您正在将模棱两可的值传递给条件循环。

当你写:

<cfloop condition="x">

您是在告诉 ColdFusion:只要“x”评估为真,就继续循环。这可能是一个类似 (myvar gte 10) 的语句,如果 myvar 大于或等于 10,它将评估为真。如果循环内的某些机制递减 myvar,最终,通过循环将导致它停止,因为myvar 将不再大于或等于 10(它已降至 10 以下)。

现在,让我们看看你的情况:

<cfloop condition="true">

CF 是否将其视为:

<cfif 'true'>

或者

<cfif TRUE>

如果您写入 ColdFusion 语句,则肯定是错误的,并且会引发错误。您可能会发现您无法将“字符串”评估为布尔值 TRUE 或 FALSE 评估。我几乎可以肯定,字符串值的解析会将 ColdFusion 与实际的布尔 TRUE 或 FALSE 值混淆。可能是这种“真”到 TRUE 的词法转换导致了与对象相关的错误。你想要的,很可能是:

因为 done 的值设置为 FALSE 以启动,当与逻辑 NOT 结合时,其计算结果为 true。

然后,稍后记录您的声明:

   <cfif quantityRemaining LTE 0>
        <cfset done = true />
   </cfif>

不需要<cfbreak>声明,它会强行使您跳出循环。如果您有条件地循环,则对该变量的评估将影响循环的迭代(阅读:它将停止它)。

此外,您可能非常希望将您的条件更改为:

<cfloop condition="quantity LTE 0">

并且根本不需要 done 变量。

于 2011-10-12T20:10:05.163 回答
1

quantityRemaining从您的代码看来,如果值达到 0 或更低,您想跳出循环。那么为什么不使用它作为cfloop 中的条件,而不是使用'true'。然后您可以删除 cfbreak 块,因为这基本上就是 cfloop 条件正在做的事情。

<cfset quantityRemaining = 5>
<cfloop condition="quantityRemaining GT 0">
    <!--- your code here --->
    <cfoutput>#quantityRemaining#<br></cfoutput>

    <!--- don't forget to change the value, otherwise you'll loop forever --->
    <cfset quantityRemaining = quantityRemaining - 1>
</cfloop>
于 2011-10-12T21:00:23.687 回答
1

错误“无法将复杂对象类型转换为简单值。 ”就是这个意思。

复杂对象 -对象、数组、结构、查询等- 无法转换为简单值 -字符串、数字、日期、布尔值等- 因为没有全局定义的方法。

根据您发布的代码,这些变量中至少有一个不包含简单的值:

  • currentCartItemCount
  • currentTubItemCount
  • lineitem.quantity
  • this.itemsPerCart
  • this.itemsPerTub
  • 剩余数量

要找出是哪一个,请将其放在循环之前:

<cfdump var=#isSimpleValue(currentCartItemCount)# />
<cfdump var=#isSimpleValue(currentTubItemCount)# />
<cfdump var=#isSimpleValue(lineitem.quantity)# />
<cfdump var=#isSimpleValue(this.itemsPerCart)# />
<cfdump var=#isSimpleValue(this.itemsPerTub)# />
<cfdump var=#isSimpleValue(quantityRemaining)# />
<cfabort/>

如果有任何输出false(或no),则打开isSimpleValue函数以找出它包含的内容并向后跟踪代码以找出原因。

如果您得到true(或yes)六次,则说明发生了其他事情,您可能需要共享更多代码。

于 2011-10-12T23:08:00.240 回答
0
<cfloop condition="true">

是相同的

<cfloop condition=true>

就像<cfif 'true'>一样<cfif true>

您基本上设置的是一个无限循环,因为您的条件将始终为真。如果您的代码永远不会中断,那么您将遇到严重的麻烦。

您可能想要做的是以下内容,并<cfbreak>从循环中删除。

<cfloop condition="quantityRemaining GT 0">
于 2011-10-13T12:49:43.940 回答