When did guard let foo = foo become legal?

Back in November 2016, I asked a question why I could not use guard to create a deployed version of a variable with the same name as an optional one, as you can if let:

Link: Why is protection not enabled foo = foo?

When I wrote this question, the code below could not compile with an error that "Definition conflicts with the previous value":

//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 } 

However, I just found code at work that does this, and now it compiles without complaint and does what I want it to do! At startup, the print statements show that foo is optional before protection, and deployed optional after:

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

(I added the guardTest(_:) test function to my latest open source project if you want to try it. It is available on Github at https://github.com/DuncanMC/TrochoidDemo )

I am glad that this design now works the way I want it, but it is confused why it is now legal and when the change occurred.

Does anyone know of a recent change in language definition that makes this construct work where it has not been before?

+5
source share
1 answer

TL DR

guard let foo = foo is legal if foo was defined in another scope.


An example from a question related to you:

 func test() { let a: Int? = 1 guard let a = a else{ return } print("a = \(a)") } 

still not working, because the guard statement is trying to create another variable a in the same scope.

In this example:

 //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 } 

works for the same reason as in this case:

 func test(a: Int) { print(type(of: a)) // Int let a = 3.14 print(type(of: a)) // Double } 

The function parameter is defined in another area, so Swift allows you to create a local variable with the same name.

+8
source

Source: https://habr.com/ru/post/1263331/


All Articles