Константы Swift: Struct или Enum


Я не уверен, какие из них лучше определить константы. Структура или перечисление. Структура будет копироваться каждый раз, когда я использую его или нет? Когда я думаю о структуре с static let константы нет смысла, что он будет копировать все время, на мой взгляд. Но если он не будет скопирован, то не имеет значения, что я беру?

Какие преимущества дает выбор структуры или enum?

Франсиско говорит использовать структуры.

Рэй Вундерлих говорят, что использование Перечислимого. Но Я не хватает оправдания.

3 52

3 ответа:

обе структуры и перечисления работы. В качестве примера, оба

struct PhysicalConstants {
    static let speedOfLight = 299_792_458
    // ...
}

и

enum PhysicalConstants {
    static let speedOfLight = 299_792_458
    // ...
}

работа и определение статического свойства PhysicalConstants.speedOfLight.

Re: структура будет копироваться каждый раз, когда я использую его или нет?

и struct и enum - это типы значений, которые также применяются к перечислениям. Но это не имеет значения здесь потому что вам не нужно создавать значение вообще: Статические свойства (также называемые тип свойства) - это свойства самого типа, а не экземпляра этого типа.

re: Какие преимущества имеет выбор структуры struct или enum?

как говорится в ссылка на статью:

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

так для структуры,

let foo = PhysicalConstants()

создает (бесполезное) значение типа PhysicalConstants, но для перечисления без регистра он не компилируется:

let foo = PhysicalConstants()
// error: 'PhysicalConstants' cannot be constructed because it has no accessible initializers

вот короткий ответ: ваши константы должны быть уникальными? Затем используйте перечисление,которое обеспечивает это.

хотите использовать несколько различных констант, чтобы содержать одно и то же значение (часто полезно для ясности)? Затем используйте структуру, которая позволяет это.

использование Xcode 7.3.1 и Swift 2.2

хотя я согласен с Мартином R, и руководство по стилю Ray Wenderlich делает хороший момент, что перечисления лучше почти во всех случаях использования из-за того, что это чистое пространство имен, есть одно место, где используется struct козырять enums.

переключатель заявления

начнем с версии struct:

struct StaticVars {
    static let someString = "someString"
}

switch "someString" {
case StaticVars.someString: print("Matched StaticVars.someString")
default: print("Didn't match StaticVars.someString")
}

используя структуру, это будет соответствовать и распечатать Matched StaticVars.someString.

Теперь рассмотрим в бескорпусном перечисление версия (только изменив слово struct до enum):

enum StaticVars {
    static let someString = "someString"
}

switch "someString" {
case StaticVars.someString: print("Matched StaticVars.someString")
default: print("Didn't match StaticVars.someString")
}

вы заметите, что вы получаете ошибку времени компиляции в операторе switch на case StaticVars.someString: линии. Ошибка Enum case 'someString' not found in type 'String'.

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

таким образом, вы бы изменить его следующим образом:

enum StaticVars {
    static let someString = { return "someString" }
}

switch "someString" {
case StaticVars.someString(): print("Matched StaticVars.someString")
default: print("Didn't match StaticVars.someString")
}

обратите внимание на необходимость скобок в заявлении case потому что теперь это функция.

недостатком является то, что теперь, когда мы сделали его функцией, он выполняется каждый раз, когда он вызывается. Так что если это просто простой примитивный тип, как String или Int, это не так уж плохо. Это по существу вычисленное свойство. Если это константа, которую необходимо вычислить, и вы хотите вычислить ее только один раз, подумайте о том, чтобы вычислить ее в другое свойство и вернуть это уже вычисленное значение в закрытии.

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

struct StaticVars {
    static let someString = "someString"
    private init() {}
}

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