2016-06-28 8 views
1

Swift 2 verfügt über Beschränkungen für die Verwendung bitweiser Operatoren für Bool Werte. Das ist angenehm. In ObjC war es sehr nützlich, es zu verwenden, wenn Sie jeden Operanden ausführen müssen. Zum Beispiel:Kombinieren mehrerer Bool-Rückgabewerte ohne Kurzschluss

a.isFoo() & b.isFoo() & c.isFoo() 

In diesem Fall wird die bitweise & mit jeder Methode auszuführen.

Wenn ich den logischen Operator verwenden & &, wird es die erste ausführen und wenn es falsch ist, wird der Ausdruck false zurück, ohne die anderen zwei Operanden ausgeführt wird.

Ich möchte die gleiche elegante Art und Weise, dass & Werke finden, mit Bool in Swift. Ist es möglich?

+0

Ich glaube, es gibt keine solche Operator (logisch und die keine Kurzschluss), um die Ausführung der Methode und kombiniert bedingten tun, aber man kann ein solches Unternehmen selbst erstellen. Oder speichern Sie die Ergebnisse zuerst in Variablen und machen Sie dann '&&'. – Sulthan

+5

Was Sie in Objective-C gemacht haben, war nicht "elegant". Es war skanky und du hättest es nicht tun sollen. Wenn Sie drei Methoden aufrufen möchten, rufen Sie einfach diese drei Methoden auf! Wenn Sie jedoch einen booleschen Ausdruck bilden, sollten Sie die Operatoren logic_ und nicht _bitwise_ verwenden. – matt

+1

Ich stimme dir nicht @matt. Es sieht elegant und kurz aus. Mag sein, hängt es von Codierungskultur ab. Leute, die in c/C++ vorher wie ein solcher Stil codiert haben. – Anessence

Antwort

6

Was Sie in Objective-C gemacht haben, war nicht "elegant". Es war skanky und du hättest es nicht tun sollen. Wenn Sie drei Methoden aufrufen möchten, rufen Sie einfach diese drei Methoden auf! Wenn Sie jedoch einen booleschen Ausdruck bilden, sollten Sie die logischen Operatoren und nicht die bitweisen Operatoren verwenden. So zum Beispiel:

let (ok1, ok2, ok3) = (a.isBool(), b.isBool(), c.isBool()) 
let ok = ok1 && ok2 && ok3 
+5

In Objective-C war es nicht nur skanky sondern gebrochen. Vor der 64-Bit-Laufzeit war 'BOOL' nur ein' typedef' für 'char' und hat daher 255 verschiedene Versionen von' YES'. So kann "JA & JA & JA" zu "NEIN" ausgewertet werden, während "JA && JA && JA" nicht möglich ist. Die schnellste Quelle, die ich finden konnte: https://www.bignerdranch.com/blog/bools-sharp-corners/ – Tommy

+1

@ Tommy Ja, das ist, was ich meinte. Vielleicht sollte ich das OP nicht schimpfen, weil ich diesen Fehler tatsächlich als einen Fehler gemacht habe, und mit meinen Hosen erwischt wurde, als mein Code funktionierte, bis es plötzlich nicht mehr funktionierte.Noch ein weiterer Grund, warum ich in dem Moment schreiend auf Swift zugelaufen bin, als es auftauchte. – matt

+0

Kühl. Ich dachte, dass Sie sich vielleicht nur auf die Regel "Getter, die keine Nebeneffekte haben" konzentrieren sollten, was meiner Ansicht nach auch Dinge wie "a.isBoolGivenThat" verbieten würde der ursprüngliche Autor hat für die Zwecke der Anfrage vereinfacht. Jawohl. – Tommy

2

Es gibt keinen speziellen Operator, aber ich würde es auf diese Weise wahrscheinlich tun:

if ![a.isBool(), b.isBool(), c.isBool()].contains(false) { 

oder nur

let aCondition = a.isBool() 
let bCondition = b.isBool() 
let cCondition = c.isBool() 

if aCondition && bCondition && cCondition { 

aber Sie können auch definieren Ihr eigener Betreiber dazu.

2

Sie könnten das gleiche Verhalten mit einer reduce Operation in einem Array Ihrer Methodenaufrufe, z.

/* example setup */ 
struct Foo { 
    let bar: Bool 
    init(_ bar: Bool) { self.bar = bar } 

    func isTrue() -> Bool { print("\(bar) foo!"); return bar } 
} 

let a = Foo(false) 
let b = Foo(false) 
let c = Foo(true) 

/* naturally all three method calls will execute to construct the boolean 
    array, whereafter reduce will evaluate the combined conditional statement */ 
if [a.isTrue(), b.isTrue(), c.isTrue()].reduce(true, combine: { $0 && $1 }) { 
    print("Reached this ...") 
} /* false foo! 
    false foo! 
    true foo! */ 

let d = Foo(true) 
let e = Foo(true) 
let f = Foo(true) 

if [d.isTrue(), e.isTrue(), f.isTrue()].reduce(true, combine: { $0 && $1 }) { 
    print("Reached this ...") 
} /* true foo! 
    true foo! 
    true foo! 
    Reached this ... */ 

oder z.B. Liefern Sie Ihre Methoden als variadische Argumente an eine Funktion

func foo(calls: (() -> Bool)...) -> Bool { 
    return calls.map{ $0() }.reduce(true, combine: { $0 && $1}) 
} 

let a = Foo(false) 
let b = Foo(false) 
let c = Foo(true) 

if foo(a.isTrue, b.isTrue, c.isTrue) { 
    print("Reached this ...") 
} /* false foo! 
    false foo! 
    true foo! */ 

let d = Foo(true) 
let e = Foo(true) 
let f = Foo(true) 

if foo(d.isTrue, e.isTrue, f.isTrue) { 
    print("Reached this ...") 
} /* true foo! 
    true foo! 
    true foo! 
    Reached this ... */ 
Verwandte Themen