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

Как поделиться экземпляром словаря в Swift?

В соответствии со ссылкой на язык Swift Programming, экземпляры Dictionary копируются всякий раз, когда они передаются функции/методу или назначаются константе или переменной. Это кажется неэффективным. Есть ли способ эффективно делиться содержимым словаря между двумя методами без копирования?

4b9b3361

Ответ 1

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

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

Источник: Классы и коллекции

Значение - не пытайтесь оптимизировать, прежде чем вы столкнулись с проблемами производительности!

Кроме того, не забывайте, что словари - это структуры. Когда вы передаете их в функцию, они неявно неизменяемы, поэтому нет необходимости копировать. Чтобы фактически передать изменяемый словарь в функцию, вы можете использовать параметр inout, и словарь не будет скопирован (передан по ссылке). Единственный случай, когда изменяемый словарь, переданный как параметр, будет скопирован, - это когда вы объявляете параметр как var.

Ответ 2

У вас всегда есть возможность определить собственный универсальный класс с атрибутом Dictionary:

class SharedDictionary<K, V> {
  var dict : Dictionary<K, V>

  // add the methods you need, including overloading operators
}

Экземпляры вашего SharedDictionary будут передаваться по ссылке (не копируются).

Ответ 3

Я действительно поговорил с кем-то из команды Swift сегодня о "прохождении по ссылке" в Свифте. Вот что я получил:

  • Как мы все знаем, структура передается по копии, классы проходят мимо Ссылка
  • Я цитирую: "Очень легко обернуть struct в class. Указывая на ответ GoZoner.
  • Несмотря на то, что хотя скопировать struct, любой classes, определенный в структура будет по-прежнему передаваться по ссылке.
  • Если вы хотите сделать традиционный переход по ссылке на структуру, используйте inout. Однако он специально упомянул "рассмотреть вопрос о добавлении другое возвращаемое значение вместо использования inout "при этом.

Так как Dictionary определяет KeyType и ValueType как generics:

struct Dictionary<KeyType : Hashable, ValueType>

Я считаю, что это означает, что если ваши объекты KeyType и ValueType являются объектами класса, они не будут скопированы, когда сам Dictionary будет скопирован, и вам не нужно слишком беспокоиться об этом.

Кроме того, класс NSDictionary по-прежнему доступен для использования!

Ответ 4

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

class SharedDictionary<K : Hashable, V> {
    var dict : Dictionary<K, V> = Dictionary()
    subscript(key : K) -> V? {
        get {
            return dict[key]
        }
        set(newValue) {
            dict[key] = newValue
        }
    }
}

Ответ 5

Доверяйте разработчикам языка: компилятор обычно умнее, чем вы думаете при оптимизации копий.

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