swift Registrazione di una enumerazione rapida usando NSLog



os_log swift (6)

Questo è il mio approccio:

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

Quindi, ogni volta che ho bisogno di stampare il valore grezzo:

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

fare

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

Stamperà:

Selezione della modalità corrente

Sto cercando di registrare un enum:

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

NSLog("%i", CKAccountStatus.Available)

Il compilatore si lamenta:

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

Perché? Ho provato a esprimere il valore:

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

Ma quello non vola neanche:

Cannot convert the expression's type '()' to type 'String'

Answer #1

Dai documenti Swift:

Se si ha familiarità con C, si saprà che le enumerazioni C assegnano i nomi correlati a un insieme di valori interi. Le enumerazioni in Swift sono molto più flessibili e non devono fornire un valore per ogni membro dell'enumerazione. Se un valore (noto come valore "raw") viene fornito per ciascun membro di enumerazione, il valore può essere una stringa, un carattere o un valore di qualsiasi numero intero o tipo a virgola mobile.

Quindi non puoi provare a lanciarlo su e Int. Per quanto riguarda il tuo primo problema, sembra che NSLog() stia cercando un parametro di tipo C-variabile, che non si applica alle enumerazioni Swift.


Answer #2

Vedo, le enumerazioni non sono numeri in Swift:

A differenza di C e Objective-C, ai membri di enumerazione Swift non viene assegnato un valore intero predefinito quando vengono creati. Nell'esempio CompassPoints sopra, Nord, Sud, Est e Ovest non equivalgono implicitamente a 0, 1, 2 e 3. Al contrario, i diversi membri di enumerazione sono valori completi a tutti gli effetti, con un tipo di CompassPoint definito in modo esplicito.

C'è un modo per registrare facilmente il valore, quindi? Ah, c'è:

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

Answer #3

Per le mie enumerazioni di errore che uso

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

per altre enumerazioni c'è il protocollo CustomStringConvertible che può essere usato come

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

Answer #4

Ottieni il valore Int sottostante di enum: CKAccountStatus.Available.rawValue .

Le enumerazioni non sono strettamente integer in Swift, ma se sono dichiarate con un tipo sottostante puoi ottenerle con rawValue - qualunque sia il tipo sottostante. ( enum Foo: String ti darà stringhe per rawValue , ecc.) Se un enum non ha un tipo sottostante, rawValue non ha nulla da darti. Nelle API importate da ObjC, qualsiasi enum definito con NS_ENUM ha un tipo intero sottostante (tipicamente Int ).

Se desideri stampare qualsiasi enumerazione in modo più descrittivo, potresti prendere in considerazione la possibilità di creare un'estensione del tipo enum che adotta il protocollo Printable .


Answer #5

Un enum è effettivamente opaco. Potrebbe avere valori non elaborati, che puoi ottenere; ma molte enumerazioni no. (Non devi dichiarare l'enum come se avessi un tipo, e se non lo fai, non ci sono valori grezzi.) Quello che farei è dare all'enum un metodo di description e chiamarlo esplicitamente.

L'unico modo per distinguere il valore corrente dell'enumerazione è attraverso un'istruzione switch, quindi il metodo di description gestirà ciascun caso e ogni caso dell'istruzione switch restituirà un valore descrittivo diverso.

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




nslog