Все обычные компиляторы Java слишком зрелы, чтобы сделать что-то немое, как конкатенировать строковые литералы во время выполнения. Давай проверим. Учитывая этот код:
public class CatStrings {
public static void main(String [] args) {
String a = "This is a long long long string broken up "
+ "into parts to see if the compiler "
+ "optimizes the concatenation.";
System.out.println(a);
}
}
Мой компилятор Java 8 - стандарт Oracle - делает правильную работу, как показано на выходе javap
:
stack=2, locals=2, args_size=1
0: ldc #2 // String This is a long long long string broken up into parts to see if the compiler optimizes the concatenation.
2: astore_1
3: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream;
6: aload_1
7: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
10: return
Предложенное решение является излишне сложным. Бесчисленные переназначения переменных и цикл - рецепт головной боли. Вот упрощенная альтернатива -
def dual (f, g, n):
if n == 0:
return lambda x: x
else:
return lambda x: f(dual(g, f, n - 1)(x))
add1 = lambda x: 1 + x
add2 = lambda x: 2 + x
print(dual(add1,add2,4)(3))
# 9
# (1 + 2 + 1 + 2 + 3)
print(dual(add1,add2,9)(3))
# 16
# (1 + 2 + 1 + 2 + 1 + 2 + 1 + 2 + 1 + 3)
print(dual(add1,add2,0)(3))
# 3
. Причина, по которой это работает, заключается в том, что в рекурсивной ветви мы называем dual
с замененными аргументами, dual(g,f,n-1)
. Таким образом, f
и g
меняются местами каждый раз, когда n
уменьшается до 0
, базового случая, который возвращает функцию идентификации (без операции).
Немного менее читаемая версия, но работает идентично -
def dual (f, g, n):
return lambda x: \
x if n == 0 else f(dual(g, f, n - 1)(x))