Подтвердить что ты не робот

Почему строка, массив и словарь в Swift изменились на тип значения

В строке Objc, массив и словарь являются ссылочными типами, а в Swift - все типы значений.

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

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

  • Но с точки зрения распределения памяти, типы значений и ссылочные типы одинаковы, не так ли? оба распределяли одинаковый размер памяти?

спасибо

4b9b3361

Ответ 1

Массивы, словари и т.д. в Objective-C часто изменяются. Это означает, что когда я передаю массив другому методу, а затем этот массив модифицируется за спиной другого метода, неожиданное (мягко говоря) поведение произойдет.

Используя типы массивов, словарей и т.д., этого удивительного поведения избегают. Когда вы получаете массив Swift, вы знаете, что никто не собирается изменять его за вашей спиной. Объекты, которые могут быть изменены за спиной, являются основным источником проблем.

В действительности компилятор Swift пытается избежать ненужного копирования, когда это возможно. Поэтому, даже если он говорит, что массив официально скопирован, это не значит, что он действительно скопирован.

Ответ 2

Команда Swift очень активна на официальных форумах разработчиков. Итак, я предполагаю, что, поскольку вы не спрашивали об этом, вам больше любопытно об общем понятии сообщества о том, что означает изменение, в отличие от деталей технической реализации. Если вы хотите точно понять "почему", просто спросите их:)

Объяснение, которое имеет для меня наибольшее значение, заключается в том, что объекты должны отвечать за реагирование и обновление состояния вашего приложения. Значения должны быть состоянием вашего приложения. Другими словами, Array или String или Dictionary (и другие типы значений) никогда не должны отвечать за пользовательский ввод или ввод в сеть или условия ошибки и т.д. Объекты обрабатывают это и сохраняют полученные данные в этих значениях.

Одна интересная функция в Swift, которая делает сложный Тип значения (например, словарь или пользовательский тип, например Person, в отличие от простого Float) более жизнеспособным, заключается в том, что типы значений могут инкапсулировать правила и логику, поскольку они могут иметь функции. Если я напишу тип значения Person как структуру, тогда структура Person может иметь функцию для обновления имени из-за брака и т.д. Это касается только данных, а не состояния/управления. Объекты по-прежнему будут решать WHEN и WHY обновлять имя Person, но бизнес-логику о том, как сделать это безопасно/умело, можно включить в сам тип значения. Следовательно, дает вам хороший способ увеличить изоляцию и уменьшить сложность.

Ответ 3

В дополнение к предыдущим ответам также существуют проблемы с несколькими потоками, которые следует учитывать при совместном использовании типа коллекции на основе ссылок, и нам не нужно беспокоиться о том, чтобы совместно использовать экземпляр типа Value-Based и имеет поведение Copy-On-Write. Многоядерный процессор становится все более распространенным даже на устройствах iOS, поэтому он стал более проблематичным для разработчиков языка Swift.

Ответ 4

Я не знаю, является ли это реальной идеей, но имеет историческое представление:

В начале копия массива вела себя по ссылке, когда вы изменили в ней элемент. Он вел себя по значению, когда вы изменили длину массива. Они делали это по соображениям производительности (меньше массива). Но, конечно, это было так, как я могу выразить это политически, а с трудом с Swift вообще, давайте называть его "не заботясь о хорошей структуре, если вы можете выиграть какую-то работу, вам, вероятно, никогда не понадобится", Некоторые называли это копией на запись, что не намного разумнее, потому что COW прозрачен, хотя это поведение не было прозрачным. Типичная быстрая формулировка: используйте модное слово, используйте его так, оно подходит для Swift, не заботятся о правильности.

Позже массивы получили полное поведение от копирования, что менее сбивает с толку. (Вы помните, что Swift был для читаемости. Очевидно, что в концепции Swift читаемость означает "меньше символов для чтения", но не означает "более понятное". Типичная формулировка Swift: используйте модное слово, используйте его так, как оно подходит для Swift, не забочусь о правильности. Я уже упоминал об этом?)

Итак, я думаю, что это все еще производительность плюс понятное поведение, вероятно, приводящее к меньшей производительности. (Вам лучше знать, когда в вашем коде требуется копия, и вы все равно можете это сделать, и вы получите 0-операцию от Cocoa, если исходный массив неизменен.) Конечно, они могли бы сказать: "Хорошо, ценность была ошибкой, мы изменили это". Но они никогда не скажут.

Однако теперь массивы в Swift ведут себя последовательно. Большой прогресс в Swift! Возможно, вы можете назвать это языком программирования в один солнечный день.