Есть ли способ сделать условное присваивание константам в Swift?

Я хотел бы создать неизменяемое значение, которому назначаются разные значения в зависимости от условия. В Scala я мог бы написать следующее:

    let attribs = if #available(iOS 8.2, *) {
        [ NSFontAttributeName: UIFont.systemFontOfSize(30, weight: UIFontWeightLight) ]
    } else {
        [ NSFontAttributeName: UIFont.systemFontOfSize(30) ]
    }

но поскольку инструкции Swift if не возвращают результат выполнения кода, который не работает.

Если тест был для нормального Bool, я мог бы использовать тернарный условный оператор

    let attribs = #available(iOS 8.2, *) ?
        [ NSFontAttributeName: UIFont.systemFontOfSize(30, weight: UIFontWeightLight) ]
    :
        [ NSFontAttributeName: UIFont.systemFontOfSize(30) ]

но это не работает для тестов версии iOS, я получаю следующую ошибку:

#available may only be used as condition of an 'if', 'guard' or 'while' statement.

Мне кажется, что я застрял в var, но если я также не сделаю это необязательным, я получаю двойное назначение в большинстве случаев, которое кажется таким уродливым и ненужным?

    var attribs = [ NSFontAttributeName: UIFont.systemFontOfSize(30) ]
    if #available(iOS 8.2, *) {
        [ NSFontAttributeName: UIFont.systemFontOfSize(30, weight: UIFontWeightLight) ]
    }

Спасибо за любую помощь!

Ответ 1

Сделайте объявление и присваивание в двух отдельных строках:

let attribs: [NSAttributedString.Key: Any]
if #available(iOS 8.2, *) {
    attribs = [.font: UIFont.systemFont(ofSize: 30, weight: .light)]
} else {
    attribs = [.font: UIFont.systemFont(ofSize: 30)]
}

Даже если это let, вы можете выполнять присваивание (только один раз за путь выполнения) в отдельной строке.

Ответ 2

Я думаю, вам нужно что-то вроде этого:

let value: String
if #available(iOS 9, *) {
    value = "iOS 9 is available"
} else {
    value = "iOS 9 and up only"
}
print(value) // iOS 9 is available

Ответ 3

Вы также можете сделать это

var someConstant: String {
    if #available(iOS 9, *) {
        return "iOS 9"
    } else {
        return "not iOS 9"
    }
}

Делая это, вы не можете присвоить значение переменной someConstant даже если это var а не let потому что это вычисляемое свойство

Другой способ сделать это - использовать бесплатные функции.

let someConstant: String = {
    if #available(iOS 9, *) {
        return "iOS 9"
    } else {
        return "not iOS 9"
    }
}()

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