Копирование ararys:
Массив - это класс, что означает, что он является ссылочным типом, поэтому array1 = array2 приводит к двум переменным, которые ссылаются на один и тот же массив.
Но посмотрите на этот пример :
static void Main()
{
int[] arr1 = new int[] { 1, 2, 3, 4, 5 };
int[] arr2 = new int[] { 6, 7, 8, 9, 0 };
Console.WriteLine(arr1[2] + " " + arr2[2]);
arr2 = arr1;
Console.WriteLine(arr1[2] + " " + arr2[2]);
arr2 = (int[])arr1.Clone();
arr1[2] = 12;
Console.WriteLine(arr1[2] + " " + arr2[2]);
}
мелкий клон означает, что копируется только память, представленная клонированным массивом.
Если массив содержит объекты типа значения, значения копируются;
, если массив содержит ссылочный тип, копируются только ссылки - поэтому в результате есть два массива, члены которых ссылаются на одни и те же объекты.
Чтобы создать дублированный тип ссылки с копией, где необходимо дублировать, вы должны пройти через массив и клонировать каждый элемент вручную.
Процитируем JEP Вывод типа локальной переменной JEP :
В цепочке вызовов вроде:
int maxWeight = blocks.stream() .filter(b -> b.getColor() == BLUE) .mapToInt(Block::getWeight) .max();
никто не беспокоится (или даже отмечает), что промежуточные типы
blockquote>Stream<Block>
иIntStream
, а также тип лямбда-формальностиb
явно не указаны в исходном коде.Вас это беспокоит?
, если один класс (скажем, «Репозиторий») меняет тип возвращаемого значения (например, с String на int). При явной типизации компиляция не удалась бы в классе, вызывающем «Репозиторий».
blockquote>Если у вас есть перегрузки, такие как
setText
в вашем примере, тоRepository repository = ...; myTextView.setText(repository.getFormerlyStringNowInt());
также не будет работать без вывода типа. Чтобы это не сработало, ваш стандарт кода должен требовать, чтобы результат каждой операции присваивался локальной переменной, как в
Stream<Block> stream1 = blocks.stream(); Predicate<Block> pred = b -> { Color c = b.getColor(); return c == BLUE; }; Stream<Block> stream2 = stream1.filter(pred); ToIntFunction<Block> getWeight = Block::getWeight; IntStream stream3 = stream2.mapToInt(getWeight); int maxWeight = stream3.max();
И в этот момент вы упрощаете ошибки, просто уменьшая удобочитаемость и возможность случайно использовать неправильную переменную.
Наконец, Kotlin не был создан в вакууме: дизайнеры могли видеть, что когда C # ввел локальный вывод типов в 2007 году, это не привело к значительным проблемам. Или они могли бы посмотреть на Scala, которая была у нее с начала 2004 года; у него было (и есть) множество жалоб пользователей, но локальный вывод типа не является одним из них.