Ведение журнала 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'
Ответы
Ответ 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) }