【问题标题】:ColdFusion: Get variable typeColdFusion:获取变量类型
【发布时间】:2012-06-27 19:39:58
【问题描述】:

ColdFusion <cfdump /> 标签给我的信息比 PHP 函数 var_dump() 少得多。

CF 中是否还有其他可能找出我的变量是什么类型(整数、字符串等)?

【问题讨论】:

    标签: variables types coldfusion


    【解决方案1】:

    CFML 是动态类型的,因此可以根据需要更改类型。

    您可以通过<cfdump var=#getMetadata(var)# /> 或简单地访问getMetadata(var).getName() 来查看变量的当前(JVM)类型。

    一般来说,你并不关心某事物是否是特定类型,而是它是否可以自动转换为特定类型——因此有一些函数,包括isSimpleValue、@ 987654322@、isDatevarious others

    因此,如果调用 isNumeric(string) 返回 true,那么您就知道可以将该变量用于数学目的。

    在大多数情况下,这就是普通 CF 开发人员关心的全部内容,而这个答案的其余部分可能并不重要(但当然可能仍然很有趣)。

    ColdFusion 和类型

    如果您有理由直接处理类型,则需要注意 Adob​​e ColdFusion 对类型做了一些有趣的事情 - 执行 <cfset number = 123 /> 会导致 字符串 不是数字类型。

    事实上,ACF 中的大多数简单值都是作为字符串创建的(然后在需要时自动转换为相关类型)。

    同时,并非所有简单值都存储为字符串 - 如果您使用<cfset number = 1 + 1 />,那么您会得到一个数字。

    您可以看到此代码使用的类型:

    <cfset TypeTest =
        { array   = []
        , struct  = {}
        , string  = "123"
        , number  = 123
        , boolean = true
        , date    = Now()
        , number2 = 1+1
        }/>
    
    <cfloop item="key" collection=#TypeTest# >
        <cfoutput><br/> #key# = #getMetadata(typetest[key]).getName()#</cfoutput>
    </cfloop>
    


    这段代码在CF10中的结果是这样的:

    ARRAY = coldfusion.runtime.Array
    STRUCT = coldfusion.runtime.Struct
    STRING = java.lang.String
    NUMBER = java.lang.String
    BOOLEAN = java.lang.String
    DATE = coldfusion.runtime.OleDateTime
    NUMBER2 = java.lang.Double
    

    这种冗长解释的原因是,如果 CF 在你转储时显示类型,一半的时间它会说“字符串”,不一定很有用。

    解决方法

    如果您需要了解 [潜在] 类型,那么您需要创建自己的转储标签/函数,它利用上述转换检查功能来确定您正在查看的内容并输出相关信息。

    Railo 和类型

    正如comment by Busches 中所述,Railo(另一种 CFML 引擎)在您转储时会显示类型,并且会显示正确的类型。

    这是因为 Railo 不只是将(几乎)所有内容都转换为字符串 - 它从相关类型开始,并在需要时进行转换。

    为了展示这一点,你可以运行上面的代码 sn -p,下面是针对 Railo 3.3 运行的结果:

    ARRAY = railo.runtime.type.ArrayImpl
    STRUCT = railo.runtime.type.StructImpl
    STRING = java.lang.String
    NUMBER = java.lang.Double
    BOOLEAN = java.lang.Boolean
    DATE = railo.runtime.type.dt.DateTimeImpl
    NUMBER2 = java.lang.Double
    

    如果你想要一个简单的单词类型,你可能会得到一个合理的值:

    ListLast(type,'.').replaceAll('Impl$','')
    

    (没有具体的Java->CFML转换函数——可以通过looking at the relevant source code看到cfdump是如何进行类型标注的。)

    【讨论】:

    • 非常感谢!很好的解释。
    • +1 出色的演示...谢谢彼得。我总是在创建具有数值的结构时被绊倒......你会建议转换数字数据类型以保持一致性还是那里也有相关的陷阱? IE。
    • 很好的答案,我只想指出“和各种其他人”的链接不起作用。
    • 感谢您的提醒。目前已切换到 archive.org 版本的链接,但我认为该页面的某个地方有 Adob​​e 版本。
    • 我仍然讨厌 CFML,但多亏了你,生活变得更轻松了。
    【解决方案2】:

    CF 中的变量是无类型的。正确使用它们取决于开发人员的最佳实践,但无论是整数还是字符串,CF 都会以相同的方式对待变量。

    对于结构或数组或组件/函数,可通过 CFDUMP 获得更多详细信息。

    【讨论】:

    • Railo 版本的 cfdump 实际上会向您显示转储时的变量类型。
    • 当您从某个 jar 文件调用函数时,您可能会收到以下消息:Either there are no methods with the specified method name and argument types or the parse method is overloaded with argument types that ColdFusion cannot decipher reliably. ColdFusion found 0 methods that match the provided arguments. If this is a Java object and you verified that the method exists, use the javacast function to reduce ambiguity. 这是因为 ColdFusion 将某些内容解释为整数,而 JAVA 没有。
    【解决方案3】:

    这是一个略微更新的版本。这包括额外的 ColdFusion 结构数据类型

    <cfscript>
     TypeTest = {array   = []
        , struct  = {}
        , orderedstruct = [:]
        , sortedstructNumeric = StructNew("ordered","numeric")
        , sortedstructText = StructNew("ordered","text")
        , string  = "123"
        , number  = 123
        , boolean = true
        , date    = Now()
        , number2 = 1+1
        };
    
    
    TypeTest.each(function(key, value) {
        TypeTest[key] = {"value" : value,  "meta" : getMetadata(value).getName() };
        });
    
    writedump(TypeTest);
    </cfscript>
    

    结果

    【讨论】:

      猜你喜欢
      • 2014-03-23
      • 1970-01-01
      • 2012-07-03
      • 2014-09-12
      • 2016-12-03
      • 2015-07-02
      • 1970-01-01
      相关资源
      最近更新 更多