2014-06-05 10 views
5

den folgenden Satz von Funktionen vor:Unterdrück Implizite Returns in Swift

func testFunc(someFunc: (Int[]) ->()) { 
    someFunc([1, 2, 3]) 
} 

func someFunc<T>(arr : T[]) -> T[] { 
    return arr 
} 

func someOtherFunc<T>(arr : T[]) { 
    println(arr) 
} 

// case 1 - ERROR 
testFunc() { 
    someFunc($0) 
} 

// case 2 - no error 
testFunc() { 
    println("whatever") 
    someFunc($0) 
} 

// case 3 - no error 
testFunc() { 
    someOtherFunc($0) 
} 

Es sieht aus wie in Fall 1, Swift versucht implizit, da die Funktion von der Schließung zurück someFunc() einen Wert zurückgibt. Dies wird nur ausgeführt, wenn nur eine Zeile in der Closure vorhanden ist (Implizite Rückgabe von Closures für Einzelausdrücke). Aus diesem Grund funktioniert case 2. Dies geschieht nicht, wenn die Funktion wie in Fall 3 Void ist, d. H. Sie gibt keinen Wert zurück.

Meine Frage ist, ob es eine Möglichkeit gibt, dieses Verhalten zu unterdrücken, so dass ich eine Funktion mit einem Rückgabewert als einzeiligen Ausdruck in einem Abschluss haben kann, der keinen Rückgabewert hat.

+1

"someFunc ($ 0); return"? Was ist falsch mit zwei Zeilen – sanz

+5

Das sieht aus wie ein Fehler. (@tony gibt es keinen Grund, warum Sie zusätzliche Zeilen für diesen Fall hinzufügen sollten.) Typ-Inferenz sollte die Tatsache abfangen, dass 'testFunc' eine Closure nimmt, die nichts' ->() 'zurückgibt und die automatische Rückgabe von der Einzelexpressions-Verschluss. Bitte melden Sie es an https://bugreport.apple.com/ –

+0

Ein Fehler macht mehr Sinn ... Ich dachte, ich würde verrückt werden. Fehlerbericht eingereicht, danke! –

Antwort

1

UPDATE: Nach dem Swift 1.2, ist dies kein Problem mehr

Dieser Fehler wird in Xcode beta6 existiert immer noch, ich hoffe, es wird in der Version 1.0 behoben wird, vor, dass dies ein Problem umgehen,

testFunc() { 
    someFunc($0) 

    // The explicit return statement corrects the wrong return type of the auto implicit return. 
    // It makes more sense than printing nonsense strings 
    return //TODO: remove after the bug is fixed 
} 
+0

Warum denken Sie, es ist ein "Bug"? Es tut genau so, wie es in der Spezifikation steht. – newacct

+0

@newacct lesen NicholasHs Kommentar unter der Frage, ich stimme ihm zu. –

+0

@newacct Eine weitere Quelle, auf GitHub gibt es ein ähnliches Problem durch implizite Rückgaben verursacht, sagte jemand die Apple-Jungs haben bestätigt, es ist ein Compiler-Fehler https://github.com/robb/Cartography/issues/9 –

6

Neben den genannten Lösungen:

testFunc { someFunc($0); return() } // returning Void explicitly (with or without parenthesis) 

testFunc { someFunc($0); 42 } // or, indeed, just adding a second expression 

können Sie verbrauchen auch den Rückgabewert:

testFunc { let x = someFunc($0) } 

oder einfach:

testFunc { _ = someFunc($0) } 

Rückgabewert muss immer der durch die Funktion Unterschrift versprochen Typ sein, und der Fall der impliziten Rendite ist nicht anders. Dies ist kein Fehler. Es ist einfach so, dass die impliziten Renditen so oft eine elegante Syntax sind, dass der weniger häufige Fall der nicht übereinstimmenden Typen den Zauber ein wenig bricht. Das soll nicht heißen, dass eine nette syntaktische Lösung nicht zu begrüßen wäre, zumindest wenn Void erwartet wird. Vielleicht etwas so einfach wie:

testFunc { someFunc($0) ; } // with the trailing semicolon 

Wenn ich das ärgert am meisten, wenn meine eigene Funktion mich um ihn herum zu tanzen zwingt. Ich habe ein paar Mal darauf zurückgegriffen, den Rückgabetyp explizit zu ignorieren:

func testFunc<Ignored>(someFunc: [Int] -> Ignored) { 
    someFunc([1, 2, 3]) 
} 

testFunc { someFunc($0) }