'as'和cast之间的Groovy差异

时间:2013-10-21 12:05:55

标签: grails groovy

使用Grails,这个:

[[a:1]] as grails.converters.JSON 

返回的不同于

(grails.converters.JSON)[[a:1]]

但两者都或多或少地按预期工作,所以我假设两个调用都由JSON类处理,但是由不同的方法(或参数)处理。

我知道as调用了asType方法,但是在调用强制转换时调用的是什么?

编辑:

我最初认为它不相关,但为了完整性,'as'返回

[{"a":1}]

,而铸造返回

{"a":1}

如果列表包含多个项目,则两者都返回相同的项目。此外,在这两种情况下,两个方法都返回一个对象,其类为grails.converters.JSON。

如果它添加任何值,我尝试使用Grails 2.2.4。

2 个答案:

答案 0 :(得分:4)

以下是它的工作原理:

  • grails.converters.JSON是grails'converters插件的一部分。
  • 转折点,确实在ConvertersApi中有效地使用了Groovy的asType,这确保了转换器(在本例中为JSON)基于应用程序上下文进行实例化。
  • 转换器上设置target。目标是委托(在您的示例中,列表包含一个元素[[a:1]]
  • 当您手动对集合进行类型转换时,您看到的唯一区别是目标未在转换器中设置。因此,转换期间缺少链接。
  • 根据转换器的基础知识,它会尝试将集合转换为JSONObjectJSONArray,而不会打扰目标。

以下是它的测试方法:

@Grab('org.json:json:20090211')
import grails.converters.JSON
import org.json.*

println([[a:1]] as JSON) //Gives [{"a":1}], works as expected
println((JSON)[[a:1]]) //Gives {"a":1} since target on converter is not set

//Manual typecast + set target
def op = (JSON)[[a:1]] //or op = new JSON([[a:1]])
op.setTarget([[a:1]])

println op //[{"a":1}] expected result because target is set

//Basic typecast to JSONObject
println((JSONObject)[[a:1]]) //{"a":1}

//With manual casting it behaves as if casted with JSONObject or JSONArray
assert ((JSON)[[a:1]]).toString() == ((JSONObject)[[a:1]]).toString()
assert ((JSON)[[a:1],[b:2]]).toString() == ((JSONArray)[[a:1],[b:2]]).toString()

//Extra massaging done by JSON converter on object
//which is not available when manually casted
JSONObject.valueToString([[a:1]]) //[{"a":1}]

答案 1 :(得分:1)

[[a:1]] as grails.converters.JSON 

这是由grails-converter插件(即ConvertersGrailsPlugin.groovy)处理的,其目的是让您能够非常快速地将域对象,映射和列表转换为JSON或XML,从而简化基于AJAX的应用程序的开发。该插件利用了groovy“as”运算符,并扩展了grails控制器中的render方法,直接将结果发送到输出流。它还为XML和JSON添加了Grails Codecs机制。在哪里:

(grails.converters.JSON)[[a:1]]

是对JSON对象的类型转换。我认为它将帮助您理解这些是两个不同的方面,而不是由JSON类处理。 :)