打开字符串值会在Groovy中产生意外结果

时间:2016-07-01 00:42:54

标签: string grails groovy switch-statement

我正在设置groovy / grails,并且在尝试对String值执行switch语句时遇到一些麻烦。

基本上,我循环遍历webservice响应中的属性名称,以查看它们是否与基于每个用户配置的预定义映射相匹配。如果他们已经在该字段上建立了映射,我将该值从响应中拉出并在其他地方使用它。

代码看起来像这样:

switch(attributeName)
{
    case {attributeName} :
        log.info("Currently switching on value... ${attributeName}")

    case user.getFirstNameMapping():
        model.user.userInfo.firstName = attributeValue
        break
    case user.getLastNameMapping():
        model.user.userInfo.lastName = attributeValue
        break
    case user.getAuthenticationKeyMapping():
        model.authenticationValue = attributeValue
        break
    case user.getEmailMapping():
        model.email = attributeValue.toLowerCase()
        break
}

正在打开的值(attributeName)是String类型,用户实例的getter方法也返回String类型。

根据我对Groovy语言的研究和理解,切换一个Object(如String)应最终使用String.equals()进行比较。然而,结果是它每次匹配user.getFirstNameMapping()的情况,并反复覆盖模型中的值;因此,响应中返回的最后一个值是最终保存的值,并且不保存任何其他值。

有趣的是,如果我使用if / else结构并执行类似的操作:

if(attributeName.equals(user.getFirstNameMapping())
{
    ...
}

每次都很好。我通过记录验证了它并不像额外的空白或大写问题那样愚蠢。我也尝试改变一些事情来默认运行开关,并在这种情况下显式比较attributeName:

switch(true)
{
    case {attributeName} :
        log.info("Currently switching on value... ${attributeName}")
    case {user.getFirstNameMapping().equals(attributeName)}:
        model.user.userInfo.firstName = attributeValue
        break
    case {user.getLastNameMapping().equals(attributeName)}:
        model.user.userInfo.lastName = attributeValue
        break
    case {user.getAuthenticationKeyMapping().equals(attributeName)}:
        model.authenticationValue = attributeValue
        break
    case {user.getEmailMapping().equals(attributeName)}:
        model.email = attributeValue.toLowerCase()
        break
}

它仍然无法以完全相同的方式满足我的期望。所以,我想知道为什么当switch语句应该只使用.equals()来比较字符串时这就是行为,当我在if / else中使用.equals()明确地比较它们时,它就像预期

2 个答案:

答案 0 :(得分:1)

问题出在你的案例中。

看看这里: -

case {attributeName} :
        log.info("Currently switching on value... ${attributeName}")

case user.getFirstNameMapping():
        model.user.userInfo.firstName = attributeValue
        break

正如您所看到的,这两种情况每次都会运行,因为切换条件是: -

switch(attributeName)

所以第一个将获得匹配并将一直运行直到遇到休息;在案例2之后,即case user.getFirstNameMapping():所以我建议你在开始之前打印{attributeName}的值。

希望能帮助你。

由于

答案 1 :(得分:0)

我不确切地知道你的问题是什么,但是case语句工作正常,即使使用方法也是如此。看我的例子

String something = "Foo"

class User {
  String firstName
  String lastName
}

User u = new User(firstName: 'Something', lastName:'Foo')

switch(something) {
  case u.getFirstName(): 
    println "firstName: ${u.firstName}"
    break;
  case u.getLastName():
    println "lastName: ${u.lastName}"
    break;
  default:
    println "nothing..."
}

此代码将按预期打印lastName。