【问题标题】:Coldfusion - Structure and dynamic variables namesColdfusion - 结构和动态变量名称
【发布时间】:2017-06-26 12:31:20
【问题描述】:

我在获取和处理包含动态变量名称的结构时遇到问题。我有一个结构 cfStruct,其中包含另一个结构 EMAILS。在最后一个结构中,项目的最大值是 4

这是我的 EMAILS 结构

EMAILS":{"1":"mail1@test.com","2":"mail2@test.net","3":"mail3@test.fr"}

我尝试为此结构的每个项目创建一个变量,如果它存在的话。然而它不起作用:

    <cfif IsDefined("cfStruct.EMAILS")>
        <cfloop from="1" to="5" index="i">
            <cfif StructKeyExists( cfStruct.EMAILS, '#i#' ) >
                <cfset setVariable( "EMAIL_#i#", "#cfStruct.EMAILS.i#" >
            <cfelse>
                <cfset setVariable( "EMAIL_#i#", '') >
            </cfif>
        </cfloop>       
    <cfelse>

你能帮我解决这个问题吗?

问候,

【问题讨论】:

  • 这个怎么样?

标签: coldfusion structure coldfusion-11 dynamic-variables


【解决方案1】:

我认为最简洁的写法是:

<cfloop from="1" to="5" index="i">
    <cfif StructKeyExists( cfStruct.EMAILS, i ) >
        <cfset variables["EMAIL_#i#"] = cfStruct.EMAILS[i] >
    <cfelse>
        <cfset variables["EMAIL_#i#"] = '' >
    </cfif>
</cfloop>

出于以下原因:

  • 没有不必要的字符串表达式。每次您执行'#i#' 时,您都在告诉 CF 解析字符串,计算其中的表达式,并返回一个新字符串来代替这个字符串。..
  • 显式优于隐式,使用 variables["EMAIL_#i#"] 可以准确地告诉您将创建的变量放在哪里,因此当您在几个月后重新阅读时,会清楚地知道发生了什么。

奖金

如果您将循环更改为 &lt;cfloop from="1" to="#structCount(cfStruct.EMAILS)#" index="i"&gt;,那么您的代码将不会创建比需要更多的变量(如果需要这种效果),并且可以扩展到任意数量的结构值。

【讨论】:

  • 好点。 “返回一个新字符串代替这个”同意,使用引号是不必要的,但我相信 CF 仍然会返回相同的字符串。除非您通过say ...添加字符或使用连接来更改值。
  • 它确实会返回相同的值,但它会在插值例程期间产生额外的数据,这些数据需要被垃圾收集,并在此之前保留内存。记住字符串在 Java 中是不可变的总是值得的,所以每当您更改修改字符串时,您可能会使用比必要更多的资源并相信编译器会为您优化字符串操作。
  • 是的,但是 java 有字符串池。由于字符串没有改变,我认为它会从池中拉出来。你有没有读过任何说 CF 行为不同的东西?我很好奇 CF 是如何处理它的,但找不到关于该主题的任何明确内容:)
  • 字符串没有改变,但创建的第一个字符串是 '#i#' 作为文字,cf 可以采取许多方法,但他们对如何做到这一点并不太透明。但我所知道的是,很长一段时间以来,lucee 及其前身 railo 执行字符串插值的速度比 cf 快,并且在可能的情况下使用连接技术构建字符串在 cf 上运行得更快。然而,这种差异仅在较大的数据集上才明显。正确的技术将允许编译器生成更优化的字节码,并且差异是/可测量的。
  • 是的,但字符串文字通常是实习的。因此,在这种情况下,CF 不会 创建新字符串的可能性更大。不过,我肯定可以看到连接是不同的,因为它可能会创建许多不同的字符串,具体取决于它的实现方式。无论哪种方式,由于内部行为未知,IMO 说“返回一个新字符串”并不完全准确,因为我们不确定 CF 在幕后的行为方式;-)也就是说,我同意应该避免这种不必要的引用。
【解决方案2】:

我解决了这是一个语法问题:

    <cfloop from="1" to="5" index="i">
        <cfif StructKeyExists( cfStruct.EMAILS, '#i#' ) >
            <cfset setVariable( "EMAIL_#i#", "#cfStruct.EMAILS[i]#") >
        <cfelse>
            <cfset setVariable( "EMAIL_#i#", '') >
        </cfif>
    </cfloop>

【讨论】:

    【解决方案3】:

    严格来说,您应该使用 cfStruct.EMAILS["#i#"] 而不是 "#cfStruct.EMAILS[i]#"。也就是说,

    <cfloop from="1" to="5" index="i">
        <cfif StructKeyExists( cfStruct.EMAILS, "#i#" ) >
            <cfset setVariable( "EMAIL_#i#", cfStruct.EMAILS["#i#"]) >
        <cfelse>
            <cfset setVariable( "EMAIL_#i#", '') >
        </cfif>
    </cfloop>
    

    【讨论】:

      猜你喜欢
      • 2012-08-31
      • 1970-01-01
      • 2017-06-13
      • 1970-01-01
      • 2012-08-30
      • 1970-01-01
      • 2014-09-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多