2017-01-25 7 views
5

Powrót w listopadzie 2016 roku wysłałem pytanie pytaniem, dlaczego nie mogę korzystać straż stworzyć nieopakowanych wersję zmiennej używając tej samej nazwy jako opcjonalny, jak można z niech jeżeli:Kiedy "strażnik niech foo = foo" staje się legalny?

Link: Why isn't guard let foo = foo valid?

Kiedy pisałem to pytanie, poniższy kod nie powiedzie się skompilować z błędem, że „konflikty definition z poprzedniej wartości”:

//Test of using guard to create an unwrapped version of a var, like if let 
func guardTest(_ viewController: UIViewController?) -> UIViewController? { 
    // Check if the current viewController exists 
    print(String(describing: viewController)) 
    guard let viewController = viewController else { 
    return nil 
    } 
    print(String(describing: viewController)) 

    return viewController 
} 

jednak ja po prostu znaleźć jakiś kod w pracy, że robi to, i teraz kompiluje bez skargi i robię to, co chcę! Po uruchomieniu wydruku sprawozdania pokazują, że foo jest opcjonalnym przed straży, i rozpakowany opcjonalnie po:

viewController = Optional(<TrochoidDemo.ViewController: 0x7ff16a039a00>) 
viewController = <TrochoidDemo.ViewController: 0x7ff16a039a00> 

(dodałem funkcję testową guardTest(_:) do mojego najnowszego projektu open source, jeśli chcesz go wypróbować. jest ona dostępna na Github na https://github.com/DuncanMC/TrochoidDemo)

Cieszę się, że konstrukcja ta działa teraz jak chcę go, ale mylić co do dlaczego to teraz legalne, a kiedy nastąpiła zmiana.

Czy ktoś wie o ostatniej zmianie w definicji języka, która sprawia, że ​​konstrukcja działa tak, jak poprzednio?

+3

To nadal nie działa, aby przedefiniować inną lokalną zmienną w funkcji. Wydaje się, że jest to związane z faktem, że Swift pozwoli ci utworzyć lokalną zmienną, która ma taką samą nazwę jak parametr wejściowy do funkcji. Nie wiem, czy to zawsze działało, ale 'var a = a' jest teraz sposobem przekształcania parametru wejściowego w' var', ponieważ nie można już wstawić znaku var do funkcji. – vacawama

+2

OK, dlaczego głosy na dół? Jeśli uważasz, że moje pytanie jest złe, proszę wyjaśnij dlaczego. –

+2

Ja głosowałem oczywiście. Każde pytanie kwestionujące coś, co moim zdaniem dobrze zrozumiałem, jest dobrym pytaniem w mojej książce. Życzę Wam, aby zmusił was do sporządzenia (konstruktywnego, miejmy nadzieję) komentarza podczas głosowania w dół lub co najmniej w głosowaniu na konstruktywną uwagę kogoś innego. – vacawama

Odpowiedz

8

TL; DR

guard let foo = foo jest legalny, jeśli foo zdefiniowano w innym zakresie.


Przykład z połączonego pytanie:

func test() 
{ 
    let a: Int? = 1 

    guard let a = a else{ 
    return 
    } 
    print("a = \(a)") 
} 

nadal nie działa, ponieważ oświadczenie guard próbuje utworzyć kolejną zmienną a w tym samym zakresie.

Ten przykład:

//Test of using guard to create an unwrapped version of a var, like if let 
func guardTest(_ viewController: UIViewController?) -> UIViewController? { 
    // Check if the current viewController exists 
    print(String(describing: viewController)) 
    guard let viewController = viewController else { 
    return nil 
    } 
    print(String(describing: viewController)) 

    return viewController 
} 

prace z tego samego powodu, że to robi:

func test(a: Int) 
{ 
    print(type(of: a)) // Int 

    let a = 3.14 

    print(type(of: a)) // Double 
} 

parametr do funkcji jest zdefiniowana w innym zakresie, tak Swift pozwala na tworzenie lokalnego zmienna o tej samej nazwie.

+2

OK, to ma sens. Dzięki za wyczyszczenie.Wydaje się dziwne, że twój przykład jest legalny, ponieważ twoje "let a = 3.14" sprawia, że ​​parametr jest niedostępny. –

+0

To się dzieje przez cały czas. Zmienne lokalne ukrywają inne zmienne przed załączaniem zakresów. Rzeczą, która mnie zastanawia, jest to, dlaczego pierwszy "print (type (of: a))" nie daje błędu, ale w tym przypadku "pozwala a = 3 func test() { druk (typ (z: a)) niech a = 3,14 drukiem (typu (z: a)) } ' – vacawama

+0

myślę parametrów do funkcji jako w zakresie lokalnym, a nie zakres załączając. Ta dyskusja wyjaśnia, że ​​parametry są faktycznie uważane za pochodzące z otaczającego zakresu. Zatem 'var a = a' jest legalne, gdy a jest parametrem, ponieważ pobiera stałą z otaczającego zakresu i redefiniuje ją jako zmienną w bieżącym zakresie. –

Powiązane problemy