2016-10-25 4 views
15

Ich konvertierte von Swift 2 zu Swift 3. Ich habe festgestellt, dass ich einen booleschen Wert nicht in Ganzzahl-Wert in Swift 3 konvertieren kann: \.Konvertieren boolescher Wert in Integer-Wert in Swift 3

let p1 = ("a" == "a") //true 

print(true)   //"true\n" 
print(p1)    //"true\n" 

Int(true)    //1 

Int(p1)    //error 

Zum Beispiel arbeitete diese Syntaxen fein in swift 2. Aber in schnellen 3 ergibt print(p1) einen Fehler.

Der Fehler ist error: cannot invoke initializer for type 'Int' with an argument list of type '((Bool))'

Ich verstehe, warum die Fehler passiert. Kann jemand erklären, was der Grund für diese Sicherheit ist und wie man in Swift 3 von Bool zu Int konvertiert?

+0

Für Swift 4, meine [akzeptierte Antwort] sehen (https://stackoverflow.com/a/44423340/1966109) für eine ähnliche Frage. –

Antwort

14

Try this,

print(true)   //"true\n" 
print(p1)    //"true\n" 

Int(true)    //1 

Int(NSNumber(value:p1)) //1 
27

Sie könnten den ternären Operator verwenden, um einen Bool zu konvertieren Int:

let result = condition ? 1 : 0 

result wird 1, wenn condition wahr ist, 0 ist condition falsch ist.

+1

Ok, also ist das Umsetzen von Boolean auf Integer ein No Go in Swift 3? –

+0

@S_kar Ja, es wurde entfernt. Ich kenne den offiziellen Grund nicht - aber das Swift-Team hat bereits erklärt, dass sie versuchen werden, jegliche "implizite/nicht-klare" Konvertierung aus der Standardbibliothek zu entfernen, und ich denke, dass diese Bool-zu-Int-Konvertierung in diese Kategorie fällt . – Moritz

+2

Ich glaube nicht, dass diese Konvertierung wirklich Teil von Swift war. Ich glaube, es war ein Nebeneffekt von impliziten Konvertierungen durch NSNumber. Implizite Bool/Int-Konvertierungen sind eine alte Fehlerquelle in C (insbesondere weil Zahlen ungleich Null wie "2" "wahr-isch", aber nicht "wahr" sind). Swift hat aktiv versucht, diese historischen Fehlerquellen zu vermeiden. –

6

EDIT - Aus den Gesprächen in den Kommentaren wird deutlicher, dass der zweite Weg (Int.init overload) eher im Stil von Swift liegt.

Alternativ könnten Sie, wenn Sie etwas in Ihrer App tun, ein Protokoll erstellen und jeden Typ, den Sie konvertieren möchten, damit auf Int erweitern.

extension Bool: IntValue { 
    func intValue() -> Int { 
     if self { 
      return 1 
     } 
     return 0 
    } 
} 

protocol IntValue { 
    func intValue() -> Int 
} 

print("\(true.intValue())") //prints "1" 

Bearbeiten- ein Beispiel für die unten von Rob Napier in den Kommentaren erwähnt Fall abzudecken, könnte man so etwas tun:

extension Int { 
    init(_ bool:Bool) { 
     self = bool ? 1 : 0 
    } 
} 

let myBool = true 
print("Integer value of \(myBool) is \(Int(myBool)).") 
+0

Oder kombinieren @ eric-aya 's ternary op-Empfehlung mit einem Protokoll für maximale Prägnanz! – diatrevolo

+0

Dieser Ansatz wurde vom Kernteam von Swift generell abgelehnt. Sie empfehlen "Int.init" -Überladungen anstelle von Methoden zur Durchführung von Conversions in voller Breite. –

+0

Jede Dokumentation, die ich in diesem Sinne lesen könnte @ Rob-Napier? Ich würde gerne mehr darüber wissen, warum es entmutigt ist und die Diskussion zu dieser Entscheidung führt. – diatrevolo

4

Sie könnte verwenden hashValue Eigenschaft:

let active = true 
active.hashValue // returns 1 
active = false 
active.hashValue // returns 0 
1

Ein wenig von mir versucht:

extension Bool { 
    var intValue: Int { 
     return self ? 1 : 0 
    } 
} 
+1

Beat mich! Dies ist definitiv meine bevorzugte Lösung. Es hält sich an Swift Konventionen mehr als andere Lösungen hier. – user3225395