2016-06-12 13 views
11

Sto lavorando con il metodo filter() in Swift, ma ho riscontrato un problema che non riesco a riprodurre in un parco giochi.Chiusura rapida: impossibile convertire il valore di tipo '(_) -> Bool' nel tipo di argomento previsto

Edit: caricato un progetto di esempio qui: https://www.dropbox.com/s/5ce5uyxnpb0mndf/WeirdSwifty.zip?dl=0

ho una struct Card che contiene un CardType enum:

struct Card { 
    var name = "" 
    var type : CardType 

    enum CardType { 
     case Red 
     case Black 
    } 
} 

e una classe Player che mantiene una matrice di questi Card elementi:

class Player { 
    var hand : [Card] 

    init() { 
     hand = ... 
    } 

    func redCards() -> [Card] { 
     return hand.filter({ (card) -> Bool in 
      return card.type == .Red 
     }) 
    } 
} 

Tuttavia, Xcode lancia un errore, non importa quanto cerco di formattare questa chiusura. Ho anche lasciato Xcode completare automaticamente la firma di chiusura/corpo, pensando ho avuto un errore di sintassi, ma mantiene ricreando lo stesso (giusto?) Modo:

enter image description here

Ho anche provato la modifica di ciò che genera automaticamente Xcode e fornendo una versione più semplice, senza alcun risultato:

enter image description here

Allo stesso modo:

enter image description here

Come ho già detto, non sono in grado di riprodurlo in un semplice esempio di gioco, ma non riesco a restringere cosa sia effettivamente causando il problema nel mio progetto principale.

Questo è l'unico errore nel mio progetto e se commento il metodo che contiene la chiamata filter(), si costruisce correttamente.

Questo errore è una falsa pista comune per qualche altro problema reale?

Nota: L'uso Xcode 7.3.1 (7D1014)

+0

Provare a dare carta di un tipo esplicito: 'ritorno hand.filter ({(scheda: Scheda) -> Bool in cambio card.type == .Red })' – vacawama

+2

Il codice compila bene per me ... forse prova a pulire la tua cartella di costruzione? – Hamish

+1

Non hai 'card' o' Card' definito da qualche altra parte nello stesso ambito? Il codice si compila bene anche per me. – Sulthan

risposta

17

Qualcosa flakey è happing con inferenza di tipo di Swift. Dare card un tipo esplicito e funzionerà.

return hand.filter({ (card: Card) -> Bool in return card.type == .Red }) 

Non è necessario il tipo di ritorno o il ritorno:

return hand.filter({ (card: Card) in card.type == .Red }) 

Nota: questo funziona anche:

return hand.filter({ ($0 as Card).type == .Red }) 

specificando completamente il valore enum .Red risolve il problema pure :

return hand.filter({ $0.type == Card.CardType.Red }) 

È stato menzionato nei commenti che se si sposta la definizione di Card nello stesso file del filtro, che funziona. Infatti, se dividi la definizione dell'enumerazione CardType da Card e sposta semplicemente CardType nel file con il filtro, funziona.

+0

Ciò ha funzionato, grazie - risolverà il problema. Anche il 'return' non è necessario, viene dedotto se una singola istruzione ha un valore di ritorno che corrisponde al tipo di ritorno previsto della chiusura:' return hand.filter ({(card: Card) in card.type == .Red}) ' –

+0

@CraigOtis Ha qualcosa a che fare con l'ordine di compilazione. Funziona se 'Card' è dichiarato nello stesso file di' Player'. – Sulthan

+0

Completamente specificando il tipo di enum funziona pure! 'return hand.filter ({$ 0.type == Card.CardType.Red})' – vacawama

Problemi correlati