Почему у Котлина нет явной печати?

Копирование 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]);
    }

мелкий клон означает, что копируется только память, представленная клонированным массивом.

Если массив содержит объекты типа значения, значения копируются;

, если массив содержит ссылочный тип, копируются только ссылки - поэтому в результате есть два массива, члены которых ссылаются на одни и те же объекты.

Чтобы создать дублированный тип ссылки с копией, где необходимо дублировать, вы должны пройти через массив и клонировать каждый элемент вручную.

5
задан GhostCat 6 March 2019 в 19:09
поделиться

1 ответ

Процитируем JEP Вывод типа локальной переменной JEP :

В цепочке вызовов вроде:

int maxWeight = blocks.stream()
                    .filter(b -> b.getColor() == BLUE)
                    .mapToInt(Block::getWeight)
                    .max();

никто не беспокоится (или даже отмечает), что промежуточные типы Stream<Block> и IntStream, а также тип лямбда-формальности b явно не указаны в исходном коде.

Вас это беспокоит?

, если один класс (скажем, «Репозиторий») меняет тип возвращаемого значения (например, с String на int). При явной типизации компиляция не удалась бы в классе, вызывающем «Репозиторий».

Если у вас есть перегрузки, такие как 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 года; у него было (и есть) множество жалоб пользователей, но локальный вывод типа не является одним из них.

0
ответ дан Alexey Romanov 6 March 2019 в 19:09
поделиться
Другие вопросы по тегам:

Похожие вопросы: