2014-06-05 20 views
5

Si consideri il seguente insieme di funzioni:Soppressione ritorni impliciti a 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) 
} 

Sembra che nel caso in cui 1, Swift sta cercando di tornare implicitamente dalla chiusura in quanto la funzione someFunc() restituisce un valore. Lo fa solo se c'è una sola linea nella chiusura (Ritorno implicito dalle chiusure a espressione singola) - questo è il motivo per cui il caso 2 funziona. Non lo fa se la funzione, come nel caso 3 è Void, cioè non restituisce un valore.

La mia domanda è se esiste un modo per sopprimere questo comportamento in modo che possa avere una funzione con un valore di ritorno come un'espressione a riga singola in una chiusura che non ha alcun valore di ritorno.

+1

"someFunc ($ 0); return"? Cosa c'è di sbagliato con due linee – sanz

+5

Questo sembra un bug. (@tony non c'è motivo per cui dovresti aggiungere righe aggiuntive per questo caso.) L'inferenza di tipo dovrebbe tener conto del fatto che 'testFunc' prende una chiusura che non restituisce nulla' ->() 'e dovrebbe sopprimere opportunamente il ritorno automatico di la chiusura a espressione singola. Si prega di segnalarlo a https://bugreport.apple.com/ –

+0

Un bug ha più senso ... Ho pensato che stavo impazzendo. Segnalazione di bug inviata, grazie! –

risposta

1

UPDATE: Dopo Swift 1.2, questo non è più un problema

Questo bug esiste ancora in Xcode beta6, spero che verrà risolto nella versione 1.0, prima di questo, si tratta di una soluzione alternativa

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

Perché pensi che sia un "bug"? Sta facendo esattamente come dice la specifica. – newacct

+0

@newacct leggi il commento di NicholasH sotto la domanda, sono d'accordo con lui. –

+0

@newacct Un'altra fonte, su GitHub c'è un problema simile causato da ritorni impliciti, qualcuno ha detto che i ragazzi Apple hanno confermato che è un bug del compilatore https://github.com/robb/Cartography/issues/9 –

6

Oltre alle soluzioni di cui:

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

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

È possibile anche consumare il valore restituito:

testFunc { let x = someFunc($0) } 

o semplicemente:

testFunc { _ = someFunc($0) } 

valore restituito deve sempre essere del tipo promesso dalla firma della funzione, e il caso del rendimento implicito non è diverso. Questo non è un bug. È semplicemente il fatto che i ritorni impliciti sono spesso una sintassi così elegante che il caso meno frequente dei tipi di mismatching sta spezzando un po 'l'incantesimo. Questo non vuol dire che una buona soluzione sintattica non sarebbe gradita, almeno quando è previsto lo Void. Forse qualcosa di semplice come:

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

Quando questo mi irrita di più è quando la mia funzione mi costringe a danzare intorno ad esso. Ho fatto un paio di volte ricorso a ignorare esplicitamente il tipo restituito:

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

testFunc { someFunc($0) }