返回语句之前的局部变量,这重要吗?

2022-09-01 10:47:31

抱歉,如果这是一个新手问题,但我找不到这个问题的答案。这样做是否更好:

int result = number/number2;
return result;

艺术

return number/number2;

我知道整数使用内存,所以我猜它会稍微降低性能?但另一方面,它使事情更清晰,特别是当int/string是一个长计算时。


答案 1

编辑:如果像我一样,你使用的Kotlin比Java多,那么知道IntelliJ在Kotlin中也对此进行了检查也是相关的:

变量仅用于以下返回,应内联

此检查报告局部变量,这些变量要么仅在下一个 return 语句中使用,要么报告其他变量的精确副本。在这两种情况下,最好内联这样的变量。


实际上,从PMD继承了一个名为“返回前不必要的本地”的SonarQube规则,该规则讨论了这一点。它说:

避免不必要地创建局部变量。

此规则后来被 SSLR 规则变量替换,不应声明变量,然后立即返回或抛出,这保持相同的位置:

声明一个变量只是为了立即返回或抛出它是一种不好的做法。一些开发人员认为,这种做法提高了代码的可读性,因为它使他们能够显式命名返回的内容。但是,此变量是内部实现详细信息,不向方法的调用方公开。方法名称应足以让调用方确切知道将返回的内容

我完全同意这一点。

IntelliJ(或至少Android Studio)也对这种情况有一个警告:

变量仅用于以下返回,并且可以内联

此检查报告局部变量,这些变量要么仅在下一次返回时使用,要么报告其他变量的精确副本。在这两种情况下,最好内联这样的变量。


在这种情况下,我认为性能根本不是值得担心的事情。话虽如此,正如@Clashsoft在他的评论中提到的,JIT很可能会内联变量,无论哪种方式,你最终都会得到相同的结果。


答案 2

选择您认为更具可读性的版本。

在有些合理的情况下,命名变量可以提高可读性。例如

public String encrypt(String plainString)
{
    byte[] plainBytes      = plainString.getBytes(StandardCharsets.UTF_8);
    byte[] hashPlainBytes  = enhash( plainBytes, 4 );
    byte[] encryptedBytes  = doAes128(Cipher.ENCRYPT_MODE , hashPlainBytes );
    String encryptedBase64 = Base64.getEncoder().withoutPadding().encodeToString(encryptedBytes);
    return encryptedBase64;
}

public String decrypt(String encryptedBase64)
{
    byte[] encryptedBytes = Base64.getDecoder().decode(encryptedBase64);
    byte[] hashPlainBytes = doAes128(Cipher.DECRYPT_MODE , encryptedBytes );
    byte[] plainBytes     = dehash( hashPlainBytes, 4 );
    String plainString = new String(plainBytes, StandardCharsets.UTF_8);
    return plainString;
}

在某些情况下,我们需要一个与返回类型不同的变量。这会影响类型转换和推理,从而产生显著的语义差异。

Foo foo()            vs.        Foo foo()
{                               {
                                    Bar bar = expr;
    return expr;                    return bar;
}                               }