2016-02-18 7 views

risposta

5

consideri il seguente esempio:

class C { 
    @warn_unqualified_access func foo(x: Int) -> Int { return x } 
    @warn_unused_result func bar(x: Int) -> Int { return foo(x) } 
} 

func main() { 
    let c = C() 
    c.foo(1) 
    c.bar(1) 
} 

main() 

Questo genera due avvertimenti.

One in C.foo():

avvertimento: 'sé' uso di 'foo' trattato come un riferimento al metodo di istanza della classe 'C' uso mettere a tacere questo avvertimento

Questo perché ho dichiarato fooas @warn_unqualified_access, quindi significa che il compilatore vuole che fanno esplicito riferimento all'oggetto quando si accede a detto elemento. Questo perché - per esempio - chiamando print in una sottoclasse di NSView conflitti tra Swift.print e NSView.print

Il secondo avviso viene generata in main(), quando si chiama bar:

avvertimento: risultato della chiamata al 'bar' è c.bar inutilizzato (1)

Questo perché io chiamo bar(), dichiarato come @warn_unused_result, e poi scartando il suo risultato. Questo è utile, per esempio, in metodi che ti restituiscono un nuovo valore ma non hanno effetti collaterali. Se scegli di ignorare il nuovo valore, essenzialmente lavori sprecati. Il compilatore può avvisarti di farlo notare.

+0

Bella spiegazione – Padalingam

23

@warn_unused_result

Supponiamo di avere una matrice che rappresenta un mazzo di carte:

var deck: [Card] = standardDeck.shuffled() 

si vuole scrivere una funzione per affrontare una carta a un giocatore. Si vuole estrarre la scheda “top” dal mazzo, aggiungerla alla mano del giocatore, e rimuoverlo dal mazzo:

func dealCard(to player: Player) { 
    guard let card = deck.last else { fatalError("Ran out of cards") } 
    player.hand.append(card) 
    deck.dropLast() 
} 

Quando si prova la vostra applicazione, si sono perplesso. Tutte le mani dei tuoi giocatori sono piene di copie della stessa carta.

Essendo nuovo di Swift, si pensa che dropLast modifichi deck rimuovendo il suo ultimo elemento. Purtroppo, ti stai sbagliando. Restituisce un nuovo array contenente tutto tranne l'ultimo elemento di deck. (Tecnicamente restituisce un valore ArraySlice.)

Il compilatore e la libreria standard hanno cospirato per aiutarvi a capire il problema.La funzione dropLast è annotata con @warn_unused_result, in modo da Xcode mostra un avviso sul dropLast chiamata:

.../Cards.swift:85:10: Result of call to 'dropLast()' is unused 

Vedendo l'avviso, si decide di opzione-clic su dropLast e leggere la documentazione, che ti dice che cosa dropLast fa (restituisce un nuovo array), e ti rendi conto che devi cambiare la linea a questo:

deck.removeLast() 

molte, molte funzioni, nella libreria standard Swift e in altre librerie, sono utili soprattutto per quello che ritornano. Ignorare il valore restituito di una di queste funzioni è di solito un errore, quindi Swift rende facile all'autore della libreria avvisare l'utente di questo comportamento. In effetti, Swift will probably soon be modified per applicare @warn_unused_result per impostazione predefinita e per utilizzare un nuovo attributo @discardableResult sulla funzione per sopprimere l'avviso.

@warn_unqualified_access

Si erano così tanto successo con il vostro gioco di carte impressionante su iOS che hai deciso di portarlo a Mac OS X. In Mac OS X, si utilizza invece di NSViewUIView per mostrare le cose sullo schermo . Si sta cercando di capire il motivo per cui la vostra abitudine CardView si sta disegnando in modo non corretto, in modo che si desidera chiamare funzione standard print di Swift in drawRect:

class CardView: NSView { 

    var card: Card 

    override func drawRect(dirtyRect: NSRect) { 
     print("Drawing \(card)") 

     // drawing code here... 
    } 

    // rest of CardView here... 
} 

Quando si esegue la vostra applicazione, siete sorpresi di scoprire che risalga il dialogo di stampa! Cosa sta succedendo? Il compilatore e NSView hanno cospirato per aiutarti a capire il problema. La funzione NSView.print è annotata con @warn_unqualified_access, in modo da Xcode mostra un messaggio di avviso sulla chiamata print:

.../CardView.swift:95:9: Use of 'print' treated as a reference to instance method in class 'NSView' 

Vedendo l'avviso, è l'opzione-clic su print e leggere la documentazione. Si apprende che NSView ha il proprio metodo print, che consente all'utente di stampare il contenuto della vista su carta. Che buffo! Ora ti rendi conto che è necessario modificare la chiamata usare esplicitamente la funzione di Swift print come questo:

 Swift.print("Drawing \(card)") 

(E 'praticamente impossibile sviluppare per Mac OS X a Swift senza incorrere in questo caso particolare ripetutamente..)

Questo tipo di problema è molto meno comune dell'altro problema di ignorare il risultato di una funzione. NSView.print è l'unico caso in cui posso richiamare l'esecuzione.

+2

Bella spiegazione! Il ragionamento alla base dell'uso di questi attributi è tanto importante quanto il loro effetto. :-) –