Code Monkey home page Code Monkey logo

Comments (14)

 avatar commented on June 11, 2024

There are times when you want to make a variable that should never be nil, but it has to be nil for a little while. That's because of the rules for Swift initialization -- you need to initialize ALL of your variables prior to calling super init, but sometimes you want to init a variable via a method in your code. However, you cannot call such a method until after calling super.init

Therefore, the best solution I have figured out is to declare the variable as implicitly unwrapped optional. That lets the compiler get through the initializer, and then I can assign a variable and assuming in my code everywhere that it is never nil because I know I never want it to be nil. Otherwise, I need to unwrap it every time I use it, or add a bunch of if-checks that I know will never fail.

--------- Original Message --------- Subject: [swift-style-guide] Implicitly unwrapped variables (varName!) (#10)
From: "Jack Wu" [email protected]
Date: 6/10/14 12:13 pm
To: "raywenderlich/swift-style-guide" [email protected]

It seems to me that implicitly unwrapped variables are there mostly to bridge from ObjC, since they behave almost identically to ObjC variables.
In pure Swift code using Optionals or regular variables should be enough. The only case where an implicitly unwrapped variable is needed is for IBOutlet, but I believe if you attach IBOutlet the variable is inferred to be implicitly unwrapped.
However, implicitly unwrapped variables do make the code easier to read since you can get away without using optional binding at times.
Personally I'm leaning towards no declaring variables with varName! at all and embrace Optionals and optional binding/chaining where needed.

Reply to this email directly or view it on GitHub.

from swift-style-guide.

hollance avatar hollance commented on June 11, 2024

I get the feeling this is a corner case that's making the language unnecessarily more complicated. Swift seems to have quite a few of these corner cases, which has me a little worried.

from swift-style-guide.

 avatar commented on June 11, 2024

I'm really hoping they correct this with what I really want, which is a property that is externally readonly but internally settable. Then I could make a nicer solution.

--------- Original Message --------- Subject: Re: [swift-style-guide] Implicitly unwrapped variables (varName!) (#10)
From: "Matthijs Hollemans" [email protected]
Date: 6/10/14 12:41 pm
To: "raywenderlich/swift-style-guide" [email protected]
Cc: "elephantronic" [email protected]

I get the feeling this is a corner case that's making the language unnecessarily more complicated. Swift seems to have quite a few of these corner cases, which has me a little worried.

Reply to this email directly or view it on GitHub.

from swift-style-guide.

hollance avatar hollance commented on June 11, 2024

File a bug report! :-)

from swift-style-guide.

jackwu95 avatar jackwu95 commented on June 11, 2024

@elephantronic I think Apple tried to address this issue with @lazy variables, but in your particular case that doesn't help either.

In your case, I believe you should be using a read-only computed variable backed by an optional.
An example of this is in the core data stack.

Basically:
var myVar { get: { return _myVar! } }
var _myVar?

Yes you will get a runtime exception if _myVar is nil when you access it but Apple appears to be fine with that in the Core Data Stack since you should be certain it is available.

from swift-style-guide.

 avatar commented on June 11, 2024

But here's where I'm confused: isn't _myVar also a property? Doesn't that mean I have just exposed the variable to the public again, making it writable?

--------- Original Message --------- Subject: Re: [swift-style-guide] Implicitly unwrapped variables (varName!) (#10)
From: "Jack Wu" [email protected]
Date: 6/10/14 1:02 pm
To: "raywenderlich/swift-style-guide" [email protected]
Cc: "elephantronic" [email protected]

@elephantronic I think Apple tried to address this issue with @lazy variables, but in your particular case that doesn't help either.
In your case, I believe you should be using a read-only computed variable backed by an optional.
An example of this is in the core data stack.
Basically:
var myVar { get: { return _myVar! } }
var _myVar?
Yes you will get a runtime exception if _myVar is nil when you access it but Apple appears to be fine with that in the Core Data Stack since you should be certain it is available.

Reply to this email directly or view it on GitHub.

from swift-style-guide.

jackwu95 avatar jackwu95 commented on June 11, 2024

Yes its public, but I guess the eventual Access controls will allow you to make _myVar private and it will work just like ObjC

from swift-style-guide.

hollance avatar hollance commented on June 11, 2024

I don't think that

var myVar { get: { return _myVar! } }
private var _myVar?      // or whatever

is cleaner and simpler than:

var myVar!

I'm no fan of the exclamation mark but it's not worth the trouble of that work-around.

Also there is no guarantee here that _myVar? will ever be set and thus doing return _myVar! may crash the app. With var myVar!, you're guaranteed that it will always have a value after the instance has been initialized.

from swift-style-guide.

jackwu95 avatar jackwu95 commented on June 11, 2024

I agree that when you start having the backing variable its not worth it anymore.

I do believe that Apple thought of this case and their should be a better way to do it than var myVar!

However, on the contrary to what you said, with var myVar! it behaves just like an Optional and defaults to nil. Thus, if you access a property of myVar later on without checking if its nil, it will throw the same exception as unwrapping a nil optional.

from swift-style-guide.

jackwu95 avatar jackwu95 commented on June 11, 2024

I just watched the session video Building Interruptible and Responsive Interactions and they faced this exact issue using UIDynamicAnimator because it requires a UIView to initialize, which is unavailable during init.

The way he did it there is to define it as an Optional and assign it in viewDidLoad. After that he accessed it directly with ! everytime without checking if its nil.

I'm not saying I like that approach, but from everything I've seen from Apple so far they don't use implicitly unwrapped optionals for class variables in native Swift code.

I think we should be consistent, and either always use var myVar! for these cases or always use var myVar? and access directly with myVar!.whatever(). I'm really torn between the two though...(Due to Apple not using ! to define variables vs the fact that it does make code much cleaner)

from swift-style-guide.

 avatar commented on June 11, 2024

Hmm. I wanted to watch that video, so maybe I'll check it out today.

I think using the implicitly unwrapped optional more clearly shows our intentions in this case, which is that the object really will always be there and the app should consider it an unrecoverable error if it is not. I feel like, if we declare a variable as optional, it really should be optional throughout the code.

I realize that because these properties are public, people could set it to nil. If you really wanted to code defensively, I suppose you could define a setter that asserted newValue is not nil

My vote is still to use it in cases where a nil value would be an error but we are still forced to use an optional for whatever reason.

--------- Original Message --------- Subject: Re: [swift-style-guide] Implicitly unwrapped variables (varName!) (#10)
From: "Jack Wu" [email protected]
Date: 6/12/14 10:56 am
To: "raywenderlich/swift-style-guide" [email protected]
Cc: "elephantronic" [email protected]

I just watched the session video Building Interruptible and Responsive Interactions and they faced this exact issue using UIDynamicAnimator because it requires a UIView to initialize, which is unavailable during init.
The way he did it there is to define it as an Optional and assign it in viewDidLoad. After that he accessed it directly with ! everytime without checking if its nil.
I'm not saying I like that approach, but from everything I've seen from Apple so far they don't use implicitly unwrapped optionals for class variables in native Swift code.
I think we should be consistent, and either always use var myVar! for these cases or always use var myVar? and access directly with myVar!.whatever(). I'm really torn between the two though...(Due to Apple not using ! to define variables vs the fact that it does make code much cleaner)

Reply to this email directly or view it on GitHub.

from swift-style-guide.

hollance avatar hollance commented on June 11, 2024

I think ! in the type name should only be used when you need it to make the init() function compile. Using it elsewhere is unsafe because you may end up with a nil value at runtime and a crash of the app. That's what ? is for.

I think it's very ugly that ! appears everywhere in the official APIs but that's just how Obj-C code gets converted to Swift. I wouldn't recommend it for your own Swift-only code.

from swift-style-guide.

 avatar commented on June 11, 2024

Yeah, that's what I'm saying, Matthijs.

However, I think I have seen some variables in Obj-C methods come over as ?. I think they are actually trying to use the two to differentiate between two possible returns: ? for methods that can safely return nil/no value and ! for those that might return nil but it would be an error if it did. But I might be misremembering and I don't want to switch gears from my other work right now to search for an example that may not even exist.

--------- Original Message --------- Subject: Re: [swift-style-guide] Implicitly unwrapped variables (varName!) (#10)
From: "Matthijs Hollemans" [email protected]
Date: 6/12/14 1:05 pm
To: "raywenderlich/swift-style-guide" [email protected]
Cc: "elephantronic" [email protected]

I think ! in the type name should only be used when you need it to make the init() function compile. Using it elsewhere is unsafe because you may end up with a nil value at runtime and a crash of the app. That's what ? is for.
I think it's very ugly that ! appears everywhere in the official APIs but that's just how Obj-C code gets converted to Swift. I wouldn't recommend it for your own Swift-only code.

Reply to this email directly or view it on GitHub.

from swift-style-guide.

rwenderlich avatar rwenderlich commented on June 11, 2024

My vote is to use ! when you are declaring a variable that you need to init early in your classes's lifecycle but not in init (such as viewDidLoad or some other), but to prefer to avoid such situations unless absolutely necessary.

from swift-style-guide.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.