2014-10-01 2 views
6

Perché a Swift è questo legale ...assert Swift con la stringa di parametri

assert(false, "Unexpected diagnosis: \(diagnosis)"); 

che tale non è?

let assertString = "Unexpected diagnosis: \(diagnosis)" 
assert(false, assertString); 

Nel secondo frammento di, ottengo l'errore ...

non può invocare 'assert' con una lista di argomenti di tipo '(BooleanLiteralConvertible, String)

Sicuramente, il secondo parametro è una stringa in entrambi i casi.

risposta

4

Il secondo parametro di asserzione è dichiarato come message: @autoclosure() -> Str o _ message: StaticString. Immagino che "Unexpected diagnosis: \(diagnosis)" sia considerato come espressione e rilevato da @autoclosure, mentre assertString è semplicemente una variabile String che non può essere convertita in chiusura o StaticString.

StaticString può essere fatto solo con:

static func convertFromExtendedGraphemeClusterLiteral(value: StaticString) -> StaticString 
static func convertFromStringLiteral(value: StaticString) -> StaticString 

Credo che questo spiega perché il manuale rapido dispone di notare che non è possibile utilizzare stringa di interpolazione in assert() in quanto non v'è alcun supporto per StringInterpolationConvertible.

+0

Wow! Grazie, è abbastanza pesante andare per qualcuno con un'esperienza <24 ore in Swift. Credo che sia l'effetto collaterale di anni di lavoro nel mondo del "pointer" che questo non era ovvio per me. Ho preso un po 'di lettura, ora lo capisco. Grazie – Fittoburst

0

forma citazione documentazioni:

... (assert()) esegui una C tradizionale stile affermare, con un messaggio opzionale. Utilizzare questa funzione per i controlli interni di integrità che sono attivi durante il test ma che non influiscono sulle prestazioni del codice di spedizione. Per verificare l'utilizzo non valido nei build di Release, vedere precondition(_:_:file:line:).

e testato su Xcode 8, precondition(_:_:file:line:) funziona perfettamente con stringhe formattate. ad esempio:

precondition(userId.lengthOfBytes(using: .ascii) > 0, "\(userId) is invalid for DBManager.id")