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

Ведение журнала Swift с использованием NSLog

Im пытается записать перечисление:

enum CKAccountStatus : Int {
    case CouldNotDetermine
    case Available
    case Restricted
    case NoAccount
}

NSLog("%i", CKAccountStatus.Available)

Компилятор жалуется:

Type 'CKAccountStatus' does not conform to protocol 'CVarArg'

Почему? Я попытался указать значение:

NSLog("%i", CKAccountStatus.Available as Int)

Но это тоже не летает:

Cannot convert the expression type '()' to type 'String'
4b9b3361

Ответ 1

Получить значение enum, лежащее в основе значения Int: CKAccountStatus.Available.rawValue.

Перечисления не являются строго целыми числами в Swift, но если они объявлены с базовым типом, вы можете получить его с помощью rawValue - независимо от того, что является базовым типом. (enum Foo: String даст вам строки для rawValue и т.д.). Если перечисление не имеет базового типа, rawValue вам нечего дать. В API, импортированных из ObjC, любое перечисление, определенное с помощью NS_ENUM, имеет базовый целочисленный тип (обычно Int).

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

Ответ 2

Перечисление эффективно непрозрачно. Это может иметь необработанные ценности, которые вы можете получить; но много перечислений нет. (Вам не нужно объявлять перечисление как имеющее тип, а если нет, то нет сырых значений.) Что бы я сделал, это предоставить enum a description метод и вызвать его явно.

Единственный способ отличить текущее значение перечисления - через оператор switch, поэтому ваш метод description будет обрабатывать каждый случай, и каждый случай оператора switch возвращает другое описательное значение.

enum Suit {
    case Hearts, Diamonds, Spades, Clubs
    func description () -> String {
        switch self {
        case Hearts:
            return "hearts"
        case Diamonds:
            return "diamonds"
        case Spades:
            return "spades"
        case Clubs:
            return "clubs"
        }
    }
}

var suit = Suit.Diamonds
println("suit \(suit.description())")  // suit diamonds

Ответ 3

Это мой подход:

enum UserMode : String
{
   case Hold = "Hold";
   case Selecting = "Selecting";
   case Dragging = "Dragging";
}

Затем, когда мне нужно напечатать необработанное значение:

//Assuming I have this declared and set somewhere
var currentMode: UserMode = .Selecting;

Выполнение

NSLog("CurrentMode \(_currMode.rawValue)");

Будет напечатан:

Выбор текущего режима

Ответ 4

Из документов Swift:

Если вы знакомы с C, вы узнаете, что перечисления C присваивают связанным именам набор целочисленных значений. Перечисления в Swift намного более гибкие и не должны предоставлять значение для каждого члена перечисления. Если для каждого элемента перечисления предусмотрено значение (известное как "необработанное" значение), это значение может быть строкой, символом или значением любого целочисленного или с плавающей точкой.

Поэтому вы не можете пытаться использовать его и Int. Что касается вашей первой проблемы, кажется, что NSLog() ищет параметр типа C-variable, который не применяется к перечислениям Swift.

Ответ 5

Я вижу, перечисления не являются числами в Swift:

В отличие от C и Objective-C, членам перечисления Swift не присваивается по умолчанию целочисленное значение при их создании. В CompassPoints пример выше, Север, Юг, Восток и Запад неявно равны 0, 1, 2 и 3. Вместо этого различные члены перечисления полноценные ценности сами по себе, с явно определенными тип CompassPoint.

Есть ли способ легко записать значение? Ах, есть:

NSLog("%i", CKAccountStatus.Available.toRaw())

Ответ 6

Вы можете использовать функцию toRaw(), чтобы получить значение Int-значения перечисления, как показано ниже:

import Foundation

enum CKAccountStatus : Int {
    case CouldNotDetermine
    case Available
    case Restricted
    case NoAccount
}

let block = {(status: Int) -> Void in
    NSLog("%d", status)
}

let status = CKAccountStatus.Available.toRaw()
block(status) // prints "1"

Ответ 7

Для перечислений Error я использую

public var localizedDescription : String { return String(reflecting: self) }

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

public var description : String { return String(reflecting: self) }