Swift should allow initializers to return nil on failure
| Originator: | brent | ||
| Number: | rdar://17296585 | Date Originated: | 12-Jun-2014 07:31 PM |
| Status: | Duplicate/16480364 | Resolved: | |
| Product: | Developer Tools | Product Version: | Xcode6-Beta (6A215l) |
| Classification: | Enhancement | Reproducible: | Always |
Summary:
Sometimes a set of parameters to an initializer just won’t work—not because of a programming error, but simply because they don’t fit the environment. For instance, any initializer that takes a URL could fail, and there’s really nothing the programmer can do to avoid it—even checking for the file’s existence before initializing just introduces a race condition.
Swift should acknowledge this and allow initializers to abort initialization and return nil.
(There is a related bug in Swift—it assumes that Objective-C initializers never return nil, when in fact they often do. This is only tangentially related to that issue, though.)
Steps to Reproduce:
1. Write a dummy class:
class X {
let data: NSData
init(URL: NSURL, error: NSErrorPointer) {
if let data = NSData(contentsOfURL: URL, options: nil, error: error) {
self.data = data
}
else {
return nil
}
}
}
2. Attempt to compile it.
Expected Results:
It, or something similar, compiles and runs successfully.
Actual Results:
An obscure error on the return line that seems to boil down to “can’t turn nil into Void”.
Notes:
For type safety’s sake, I would not allow just any initializer to return nil. Instead, I’d require the developer to mark the initializer, probably with a question mark:
init?(URL: NSURL, error: NSErrorPointer) {
You could support implicit optional initializers as well, but I wouldn’t bother; any initializer that is expected to potentially fail should be checked anyway. (You could also support them only for classes defined in Objective-C, where optional initializers are not clearly marked in the headers.)
Rather than “return nil”, you could introduce a different keyword, such as “fail”. Using “return nil” seems to be a little more parsimonious with keywords, though.
An initializer returning nil would probably require initializers calling it to immediately return nil as well. It would be an error to call an optional initializer from a non-optional one.
To ensure deinitialization works properly, Swift may need to require that the object be validly initialized, even with dummy data, and a superclass designated initializer be called, before an initializer was permitted to fail. That’d be fine.
Comments
Please note: Reports posted here will not necessarily be seen by Apple. All problems should be submitted at bugreport.apple.com before they are posted here. Please only post information for Radars that you have filed yourself, and please do not include Apple confidential information in your posts. Thank you!