Groovy中的List.each方法内部无法控制整个方法的返回

本文探讨了Java中`each`方法与常规for循环的区别,指出`each`方法可能导致的方法调用封闭特性,导致代码在找到匹配条件后立即返回false。作者提供了for循环的替代,并解释了这种行为背后的原理。

1 问题

  • each方法中的return 不会结束方法
boolean check(List personList){
	personList.each{
		if(it.name == "test"){
			return true
		}
	}
	return false
}
  • 代码永远返回 false

2 替代方式

  • 使用java中的for循环
boolean check(List personList){
	for(Person it: personList){
		if(it.name == "test"){
			return true
		}
	}
	return false
}
  • 只要存在name==“test”, 整个check方法返回true

3 原因浅谈

  • 我感觉是类似于java中的forEach方法,整个循环是一个封闭方法,隔绝了外部
  • 不确定是不是另起线程
/* * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved. */ package com.huawei.it.elogic.formula.helper import com.huawei.it.elogic.formula.constants.GroovyEvalConstant import com.huawei.it.publicsaas.framework.context.ContextUtils import org.codehaus.groovy.ast.ASTNode import org.codehaus.groovy.ast.expr.ArgumentListExpression import org.codehaus.groovy.ast.expr.BinaryExpression import org.codehaus.groovy.ast.expr.ConstantExpression import org.codehaus.groovy.ast.expr.Expression import org.codehaus.groovy.ast.expr.GStringExpression import org.codehaus.groovy.ast.expr.ListExpression import org.codehaus.groovy.ast.expr.MethodCallExpression import org.codehaus.groovy.ast.expr.TernaryExpression import org.codehaus.groovy.ast.expr.TupleExpression import org.codehaus.groovy.control.CompilePhase import org.codehaus.groovy.control.SourceUnit import org.codehaus.groovy.transform.ASTTransformation import org.codehaus.groovy.transform.GroovyASTTransformation /** * groovy的AST树转化,适配fel * * @since 2024/2/22 */ @GroovyASTTransformation(phase = CompilePhase.SEMANTIC_ANALYSIS) class DollarSignTransformer implements ASTTransformation { private static String CONSTANTEXPRESSION_METADATAMAP_KEY = "_IS_STRING" private static List<Class> NEED_CHANGE_PEXRS = Arrays.asList( BinaryExpression.class, MethodCallExpression.class, TernaryExpression.class, ArgumentListExpression.class ) @Override void visit(ASTNode[] nodes, SourceUnit source) { if (!GroovyEvalConstant.FIXED_GROOVY_VALUE.equals(ContextUtils.getValue(GroovyEvalConstant.FIXED_GROOVY_KEY))) { return } nodes.each { node -> { node.statementBlock.statements.each { statement -> { Expression expr = statement.expression if (expr instanceof GStringExpression) { statement.expression = getStringExprFromGStringExpr(expr) } else if (NEED_CHANGE_PEXRS.contains(expr.getClass())) { statement.expression = traverseExpr(expr) } } } } } } /** * 遍历expression,有子expression则递归处理 * @param expr expr */ Expression traverseExpr(Expression expr) { List<Expression> subExprs = getSubExprs(expr) for (int i = 0; i < subExprs.size(); i++) { Expression subExpr = subExprs[i] if (subExpr instanceof GStringExpression) { subExprs[i] = getStringExprFromGStringExpr(subExpr) } else if (NEED_CHANGE_PEXRS.contains(subExpr.getClass())) { subExprs[i] = traverseExpr(subExpr) } } expr = setSubExprs(expr, subExprs) return expr } /** * 将需要修改的expression的所有子expression组装成List返回 * @param exprs * @return */ private List<Expression> getSubExprs(Expression expr) { List<Expression> subExprs = new ArrayList<>() if (expr instanceof BinaryExpression) { subExprs.add(expr.leftExpression) subExprs.add(expr.rightExpression) } else if (expr instanceof MethodCallExpression) { subExprs = expr.arguments.expressions } else if (expr instanceof TernaryExpression) { subExprs.add(expr.booleanExpression) subExprs.add(expr.trueExpression) subExprs.add(expr.falseExpression) } else if (expr instanceof ListExpression) { subExprs = expr.expressions } return subExprs } /** * 将需要修改的expression的所有子expression组装成List返回 * @param exprs expr * @param newSubExprs 转化后的expression * @return 新的expression */ private Expression setSubExprs(Expression expr, List<Expression> newSubExprs) { if (expr instanceof BinaryExpression) { expr.leftExpression = newSubExprs[0] expr.rightExpression = newSubExprs[1] } else if (expr instanceof MethodCallExpression) { expr.setArguments(new TupleExpression(newSubExprs)) } else if (expr instanceof TernaryExpression) { expr = new TernaryExpression(newSubExprs[0], newSubExprs[1], newSubExprs[2]) } else if (expr instanceof ArgumentListExpression) { expr = new ArgumentListExpression(newSubExprs) } return expr } /** * GStringExpression转ConstantExpression,即$引用串转字符串 * * @param gStringExpr gStringExpr * @return ConstantExpression */ private ConstantExpression getStringExprFromGStringExpr(GStringExpression gStringExpr) { def constantExpr = new ConstantExpression(gStringExpr.verbatimText) constantExpr.lineNumber = gStringExpr.lineNumber constantExpr.columnNumber = gStringExpr.columnNumber constantExpr.lastLineNumber = gStringExpr.lastLineNumber constantExpr.lastColumnNumber = gStringExpr.lastColumnNumber Map map = new LinkedHashMap() map.put(CONSTANTEXPRESSION_METADATAMAP_KEY, true) constantExpr.metaDataMap = map return constantExpr } }
最新发布
09-06
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值