Android Studio WebView не может воспроизводить аудио

В следующем коде, почему переменная 'b' изменяется после вызова 'addup'?

Переменная не изменяется. Он по-прежнему ссылается на тот же самый массив, что и раньше.

Есть только два способа изменить переменную в Ruby:

  1. Назначение (foo = :bar)
  2. Отражение ( Binding#local_variable_set , Object#instance_variable_set , Module#class_variable_set , Module#const_set )

Ни один из них не используется здесь.

Кажется, я понимаю, почему «a» изменяется (хотя его немного нечеткое)

a также не изменяется. Он также по-прежнему ссылается на тот же массив, что и раньше. (Который, кстати, тот же массив, который ссылается на b.)

Единственное, что делает , - это внутреннее состояние массива, на которое ссылаются оба a ] и b. Итак, если вы действительно понимаете, почему изменяется массив, на который ссылается a, вы также понимаете, почему массив, на который ссылается b, изменяется , поскольку он является тем же самым массивом , В вашем коде есть только один массив.

Проблема с немедленным с вашим кодом заключается в том, что если вы хотите получить копию массива, то вам действительно нужно сделать копию массив. Вот что Object#dup и Object#clone для:

b = a.clone

Исправит ваш код.

НО!

В коде есть некоторые другие проблемы. Основная проблема - мутация . Если это вообще возможно, вы должны избегать мутации (и побочных эффектов в целом, из которых мутация является только одним примером), насколько это возможно, и использовать ее только тогда, когда вы действительно, ДЕЙСТВИТЕЛЬНО должны. В частности, вы должны never мутировать объекты, которые у вас нет, и это означает, что вы должны never мутировать объекты, которые были переданы вам в качестве аргументов.

Однако в вашем методе addup вы мутируете массив, который передается вам как arr. Мутация является источником вашей проблемы, если вы не мутировали arr, а вместо этого вернули новый массив с необходимыми изменениями, тогда у вас не было бы проблемы в первую очередь. Один из способов не мутировать аргумент - это переместить clone в метод, но есть еще лучший способ.

Еще одна проблема с вашим кодом заключается в том, что вы используете цикл. В Ruby почти никогда не бывает ситуации, когда петля является лучшим решением. Фактически, я бы зашел так далеко, чтобы утверждать, что если вы используете цикл, вы делаете это неправильно.

Петли подвержены ошибкам, трудно понять, трудно получить право, и они зависят от от побочных эффектов. Цикл не может работать без побочных эффектов, но мы просто сказали, что хотим избежать побочных эффектов!

Пример: ваш цикл содержит серьезную ошибку. Если я пройду [1, 2, 3, 4, 5], результат будет [1, 2, 3, 5]. Зачем? Из-за мутации и ручного цикла:

На четвертой итерации цикла в начале массив выглядит следующим образом:

[1, 2, 3, 4, 5]
#         ↑
#         i

После вызова delete_at(i) массив выглядит следующим образом:

[1, 2, 3, 5]
#         ↑
#         i

Теперь вы увеличиваете i, поэтому ситуация выглядит так:

[1, 2, 3, 5]
#            ↑
#            i

i теперь больше длины из массива, эрго, концы цикла и 5 никогда не удаляются.

Что вы действительно хотите, это:

def addup(arr)
  arr.reject {|el| el > 3 }
end

a = [1, 2, 3, 4, 5]
b = a

puts "a=#{a}"             # => [1, 2, 3, 4, 5]
puts "b=#{b}"             # => [1, 2, 3, 4, 5]
puts "addup=#{addup(a)}"  # => [1, 2, 3]
puts "a=#{a}"             # => [1, 2, 3, 4, 5]
puts "b=#{b}"             # => [1, 2, 3, 4, 5]

Как вы можете видеть, ничего не было мутировано. addup просто возвращает новый массив с теми изменениями, которые вы хотите. Если вы захотите позже обратиться к этому массиву, вы можете назначить его переменной:

c = addup(a)

Нет необходимости вручную запускать скриптовые индексы. Нет необходимости копировать или клонировать что-либо. На расстоянии нет «жуткий действия», как это называл Альберт Эйнштейн. Мы исправили две ошибки и удалили 7 строк кода, просто

  • , избегая мутации
  • , избегая циклов
0
задан w i ' Ø 19 January 2019 в 16:23
поделиться