2016-10-25 20 views
15

Konwertowałem z wersji 2 na szybką 3. Zauważyłem, że nie można skonwertować wartości logicznej na wartość całkowitą w swift 3: \.Konwertowanie wartości typu Boolean na wartość całkowitą w swift 3

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

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

Int(true)    //1 

Int(p1)    //error 

Na przykład te składnie pracował dobrze w szybkim 2. Ale w szybkim 3, print(p1) daje błąd.

Błąd znajduje error: cannot invoke initializer for type 'Int' with an argument list of type '((Bool))'

rozumiem, dlaczego dzieją się błędy. Czy ktoś może wyjaśnić, co jest przyczyną tego bezpieczeństwa i jak przekonwertować Bool na Int w Swift 3?

+0

Dla Swift 4, zobacz moje [zaakceptowane odpowiedź] (https://stackoverflow.com/a/44423340/1966109) na podobne pytanie. –

Odpowiedz

14

spróbować tego,

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

Int(true)    //1 

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

Można użyć operatora potrójny konwertować bool do int:

let result = condition ? 1 : 0 

result będzie 1 czy condition jest prawdą, 0 jest condition jest fałszywe.

+1

Ok, więc rzutowanie z wartości typu Boolean na liczbę całkowitą nie ma przejścia w trybie szybkim 3? –

+0

@S_kar Tak, został usunięty. Nie znam oficjalnego powodu - ale zespół Swift już oznajmił, że spróbuje usunąć jakąkolwiek konwersję typu "niejawny/nieoczywisty" ze standardowej biblioteki i, jak przypuszczam * ta konwersja Bool na Int należy do tej kategorii . – Moritz

+2

Nie wierzę, że ta konwersja była naprawdę częścią Swift. Uważam, że był to efekt uboczny niejawnych konwersji za pośrednictwem NSNumber. Niejawne konwersje Bool/Int są starym źródłem błędów w C (w szczególności, ponieważ niezerowe liczby, takie jak "2", to "true-ish", ale nie są równe "true"). Swift aktywnie próbował uniknąć tych historycznych źródeł błędów. –

6

EDYCJA - Z rozmów w komentarzach staje się jasne, że drugi sposób wykonania tego poniżej (przeciążenie Int.init) jest bardziej zbliżony stylem do miejsca, w którym znajduje się Swift.

Ewentualnie, jeśli było to coś, co robiłeś dużo w swojej aplikacji, możesz utworzyć protokół i rozszerzyć każdy typ, który musisz przekonwertować na niego za pomocą Int.

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

protocol IntValue { 
    func intValue() -> Int 
} 

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

Edit- Aby pokryć przykład przypadku wymienionego przez Rob Napier w komentarzach poniżej, można zrobić coś takiego:

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

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

Możesz też połączyć zalecenie ternarne @ eric-aya z protokołem dla maksymalnej zwięzłości! – diatrevolo

+0

Zasadniczo to podejście zniechęciło rdzeń zespołu Swift. Zalecają przeciążenia "Int.init", a nie metody wykonywania konwersji o pełnej szerokości. –

+0

Wszelka dokumentacja, którą mógłbym odczytać w tym celu @ Rob-napier? Chciałbym dowiedzieć się więcej o tym, dlaczego jest to zniechęcenie i dyskusji prowadzącej do tej decyzji. – diatrevolo

4

Ty może użyć właściwości hashValue:

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

Trochę próbuje ode mnie:

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

Pokieruj mną! Jest to zdecydowanie moje preferowane rozwiązanie, które jest zgodne z konwencjami Swift bardziej niż innymi rozwiązaniami. – user3225395

Powiązane problemy