2016-02-18 5 views

Odpowiedz

5

Rozważmy następujący przykład:

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() 

ten generuje dwa ostrzeżenia.

Jedna C.foo():

uwaga: 'ja' zastosowanie "foo traktowane jako przykład w odniesieniu do sposobu, w klasie 'C' użytku uciszyć to ostrzeżenie

To dlatego oświadczyłem fooas @warn_unqualified_access, więc oznacza to, że kompilator chce mi wyraźnie odnoszą się do obiektu przy dostępie powiedział członek. To dlatego, że - na przykład - wywołanie print w podklasie NSView konfliktów między Swift.print i NSView.print

Drugie ostrzeżenie jest generowany w main(), gdy dzwoni bar:

ostrzeżenie: wynik wywołania „bar” jest nieużywany c.bar (1)

to dlatego wzywam bar(), deklarowane jako @warn_unused_result, a następnie odrzucając jej wynik. Jest to użyteczne na przykład w metodach, które zwracają nową wartość, ale nie mają efektów ubocznych. Jeśli zdecydujesz się zignorować nową wartość, zasadniczo marnujesz pracę. Kompilator może ostrzec cię, aby to wskazać.

+0

Dobre wytłumaczenie – Padalingam

23

@warn_unused_result

Załóżmy, że masz tablicę przedstawiającą talię kart:

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

chcesz napisać funkcję do czynienia kartę do odtwarzacza. Chcesz wyciągnąć „top” kartę z talii, dodaj go do ręki gracza, i usunąć go z pokładu:

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

Podczas testowania aplikacji, jesteś zaskoczony. Wszystkie ręce Twoich graczy są wypełnione kopiami tej samej karty.

Będąc nowicjuszem w Swift, myślisz, że dropLast modyfikuje deck, usuwając ostatni element. Niestety, jesteś w błędzie. Zwraca on tablicę nowa zawierającą wszystkie oprócz ostatniego elementu z deck. (Technicznie zwraca wartość ArraySlice.)

Kompilator i biblioteka standardowa zostały skonfigurowane w celu rozwiązania problemu.Funkcja dropLast jest opatrzone @warn_unused_result, więc Xcode wyświetla ostrzeżenie na dropLast rozmowy:

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

wyświetleniu ostrzeżenia, zdecydujesz się na opcję kliknij dropLast i zapoznać się z dokumentacją, która mówi, co dropLast robi (zwraca nową tablicę) i zdajesz sobie sprawę, trzeba zmienić linię do tego:

deck.removeLast() 

wiele, wiele funkcji, w bibliotece standardowej Swift oraz w innych bibliotekach, są przydatne przede wszystkim do czego wracać. Ignorowanie zwróconej wartości jednej z tych funkcji jest zwykle błędem, więc Swift ułatwia autorowi biblioteki ostrzeganie użytkownika o tym zachowaniu. W rzeczywistości, Swift will probably soon be modified, aby domyślnie zastosować @warn_unused_result i użyć nowego atrybutu @discardableResult w funkcji, aby wyłączyć ostrzeżenie.

@warn_unqualified_access

Byłaś tak skuteczne ze swojej wspaniałej gry karcianej na iOS że zdecydowałeś się go do portu Mac OS X. W systemie Mac OS X, należy użyć NSView zamiast UIView pokazać rzeczy na ekranie . Próbujesz dowiedzieć się, dlaczego zwyczaj CardView zbliża się nieprawidłowo, więc chcesz zadzwonić standardowego print funkcję Swift w drawRect:

class CardView: NSView { 

    var card: Card 

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

     // drawing code here... 
    } 

    // rest of CardView here... 
} 

Po uruchomieniu aplikacji, jesteś zaskoczony, że to wyskakuje okno dialogowe drukowania! Co się dzieje? Kompilator i NSView spiskowali, aby pomóc ci rozwiązać problem. Funkcja NSView.print jest opatrzone @warn_unqualified_access, więc Xcode wyświetla ostrzeżenie na wezwanie print:

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

Widząc ostrzeżenia dostępne Option na print i zapoznać się z dokumentacją. Dowiesz się, że NSView ma własną metodę print, która pozwala użytkownikowi wydrukować zawartość widoku na papierze. Jak droll! Teraz sobie sprawę, trzeba zmienić wywołanie jawnie użyć print funkcję Swift tak:

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

(Jest to praktycznie niemożliwe, aby opracować dla systemu Mac OS X w Swift bez uruchamiania w tym konkretnym przypadku wielokrotnie.).

Ten rodzaj problemu jest znacznie mniej powszechny niż inny problem polegający na ignorowaniu wyniku funkcji. NSView.print to jedyny przypadek, o którym pamiętam, że wpadłem.

+2

Niezłe wytłumaczenie! Uzasadnienie użycia tych atrybutów jest równie ważne, jak ich efekt. :-) –