Если вы хотите реализовать метод подкачки для объектов Integer, вы должны обернуть значения в массив (или ArrayList) и поменять его внутри массива. Вот адаптация вашего кода:
public class Main {
static void swap (Integer[] values) {
if ((values == null) || (values.length != 2)) {
throw new IllegalArgumentException("Requires an array with exact two values");
}
Integer t = values[0];
values[0] = values[1];
values[1] = t;
}
public static void main(String[] args) {
Integer a = 1;
Integer b = 2;
Integer[] integers= new Integer[]{a,b};
swap(integers);
System.out.println("a=" + integers[0] + " b=" + integers[1]);
}
}
(просто добавил этот ответ, потому что Svish упомянул, что «Вы действительно не можете создать метод swap в Java» фг )
Python на самом деле ведет себя, как определено. Три отдельных функции создаются, но каждый из них имеет закрытие среды, они определяются в - в этом случае, глобальная среда (или среда внешней функции, если цикл помещается в другой функции). Это - точно проблема, хотя - в этой среде, я видоизменен , и закрытия весь отсылают к тому же меня .
Вот лучшее решение, которое я могу предложить - создают функционального создателя и вызывают это вместо этого. Это вызовет различные среды для каждой из созданных функций, с отличающийся я в каждом.
flist = []
for i in xrange(3):
def funcC(j):
def func(x): return x * j
return func
flist.append(funcC(i))
for f in flist:
print f(2)
Это - то, что происходит, когда Вы смешиваете побочные эффекты и функциональное программирование.
Функции, определяемые в цикле продолжают получать доступ к той же переменной i
, в то время как ее значение изменяется. В конце цикла все функции указывают на ту же переменную, которая содержит последнее значение в цикле: эффект - то, что сообщило в примере.
, Чтобы оценить i
и использовать его значение, общий шаблон должен установить его как значение по умолчанию параметра: значения по умолчанию параметра оценены, когда def
оператор выполняется, и таким образом значение переменной цикла замораживается.
следующие работы как ожидалось:
flist = []
for i in xrange(3):
def func(x, i=i): # the *value* of i is copied in func() environment
return x * i
flist.append(func)
for f in flist:
print f(2)
посмотрите на это:
for f in flist:
print f.func_closure
(<cell at 0x00C980B0: int object at 0x009864B4>,)
(<cell at 0x00C980B0: int object at 0x009864B4>,)
(<cell at 0x00C980B0: int object at 0x009864B4>,)
Это означает, что они все указывают на то же на меня переменный экземпляр, который будет иметь значение 2, как только цикл закончен.
А читаемое решение:
for i in xrange(3):
def ffunc(i):
def func(x): return x * i
return func
flist.append(ffunc(i))
То, что происходит, - то, что переменная, я получен, и функции, возвращает значение, это связывается с тем, в то время, когда это называют. На функциональных языках никогда не возникает этот вид ситуации, поскольку я не был бы восстановлением. Однако с Python, и также как Вы видели с шепелявостью, это больше не верно.
различие с Вашим примером схемы относится к семантике, действительно циклично выполняются. Схема эффективно создает новое я переменная каждый раз через цикл, вместо того, чтобы снова использовать существующее я связывающий как с другими языками. Если Вы будете использовать различную переменную, созданную внешний к циклу, и видоизменять его, Вы будете видеть то же поведение в схеме. Попытайтесь заменить свой цикл:
(let ((ii 1)) (
(do ((i 1 (+ 1 i)))
((>= i 4))
(set! flist
(cons (lambda (x) (* ii x)) flist))
(set! ii i))
))
Смотрят здесь для некоторого дальнейшего обсуждения этого.
[Редактирование] Возможно лучший способ описать его состоит в том, чтобы думать, действительно циклично выполняются как макрос, который выполняет следующие шаги:
т.е. эквивалент ниже Python:
flist = []
def loop_body(i): # extract body of the for loop to function
def func(x): return x*i
flist.append(func)
map(loop_body, xrange(3)) # for i in xrange(3): body
я больше не является тем от родительского объема, но совершенно новой переменной в ее собственном объеме (т.е. параметр к лямбде) и таким образом, Вы получаете поведение, которое Вы наблюдаете. Python не имеет этого неявного нового объема, таким образом, тело для цикла просто совместно использует меня переменная.
Проблема состоит в том, что все локальные функции связывают с той же средой и таким образом с тем же i
переменная. Решение (обходное решение) состоит в том, чтобы создать отдельные среды (стековые фреймы) для каждой функции (или лямбда):
t = [ (lambda x: lambda y : x*y)(x) for x in range(5)]
>>> t[1](2)
2
>>> t[2](2)
4
Я полностью все еще не убежден, почему на некоторых языках это прокладывает себе путь, и некоторым другим способом. В языке Common LISP это похоже на Python:
(defvar *flist* '())
(dotimes (i 3 t)
(setf *flist*
(cons (lambda (x) (* x i)) *flist*)))
(dolist (f *flist*)
(format t "~a~%" (funcall f 2)))
Печать "6 6 6" (отмечают, что здесь список от 1 до 3, и создан наоборот"). В то время как в Схеме это работает как в Perl:
(define flist '())
(do ((i 1 (+ 1 i)))
((>= i 4))
(set! flist
(cons (lambda (x) (* i x)) flist)))
(map
(lambda (f)
(printf "~a~%" (f 2)))
flist)
Печать "6 4 2"
И как я уже упомянул, JavaScript находится в лагере Python/CL. Кажется, что здесь существует решение реализации, к которому различные языки приближаются отличными способами. Я хотел бы понять то, что является решением, точно.
Переменная i
является глобальным, значение которого равняется 2 каждый раз, функция f
вызвана.
я был бы склонен реализовать поведение, которое Вы после следующим образом:
>>> class f:
... def __init__(self, multiplier): self.multiplier = multiplier
... def __call__(self, multiplicand): return self.multiplier*multiplicand
...
>>> flist = [f(i) for i in range(3)]
>>> [g(2) for g in flist]
[0, 2, 4]
Ответ на Ваше обновление : это не глобальные из i
по сути , который вызывает это поведение, это - то, что это - переменная от объема включения, который имеет фиксированное значение за времена, когда f называют. В Вашем втором примере значение i
принято от объема эти kkk
функция, и ничто не изменяет это, когда Вы вызываете функции на flist
.