[swift-evolution] [Idea] Set variables to "_" in two-stage init; remove IUO
Charlie Monroe
charlie at charliemonroe.net
Thu Jun 16 06:37:19 CDT 2016
There's nothing stopping you from making init(frame:) and init?(coder:) convenience:
public class ColorView: NSView {
public required convenience init?(coder: NSCoder) {
self.init(frame: CGRect(x: 0.0, y: 0.0, width: 20.0, height: 20.0))
}
private convenience override init(frame frameRect: CGRect) {
self.init(color: NSColor.whiteColor())
}
public init(color: NSColor) {
super.init(frame: CGRect(x: 0.0, y: 0.0, width: 20.0, height: 20.0))
}
}
The only drawback is that init?(coder:) will always need to be public since it's `required`.
> On Jun 16, 2016, at 1:27 PM, Jonathan Hull via swift-evolution <swift-evolution at swift.org> wrote:
>
> Good question/idea.
>
> The use case I have with this most often is -initWithCoder and some other init like -initWithFrame. I don’t think you can make those convenience inits. If there is a way to make that work though, I am all for it.
>
> The thing I do most often, when possible, is lazily set each variable from a closure so that I don’t have to worry about it in the inits. I find this especially useful for creating subviews/layers. It isn’t always an option though…
>
> Thanks,
> Jon
>
>
>
>> On Jun 16, 2016, at 4:19 AM, Vladimir.S <svabox at gmail.com> wrote:
>>
>> The question is if we can solve the problem with special private init() and convenience inits ?
>>
>> class MyBase {
>> init () {
>>
>> }
>> }
>>
>> class MyClass : MyBase {
>>
>> let x:Int
>> let y:String
>> let z:Double
>>
>> private init(_ xValue: Int, _ zValue: Double) {
>> self.x = xValue
>> self.y = "\(xValue) - \(zValue)"
>> self.z = zValue
>>
>> super.init()
>> }
>>
>> convenience override init() {
>> self.init(1, 1.0)
>> }
>>
>> convenience init(x: Int) {
>> self.init(x, 1.0)
>> }
>>
>> convenience init(z: Double) {
>> self.init(1, z)
>> }
>> }
>>
>> print(MyClass().y)
>> print(MyClass(x: 10).y)
>> print(MyClass(z: 10.0).y)
>>
>> Seems like we can. Any drawbacks?
>>
>> On 16.06.2016 9:27, Jonathan Hull via swift-evolution wrote:
>>> I don’t remember a proposal for that, but I would definitely support one.
>>> I use this pattern all the time (usually by initializing to a default
>>> value first), and it would be nice to have an explicit/safe way to handle
>>> it, (and to avoid waisting cycles creating an object I never use).
>>>
>>> Perhaps we should spell it @init or @initHelp:
>>>
>>> class MyClass : MySuperClass {
>>>
>>> let x:Int
>>> let y:String
>>> let z:Double
>>>
>>> @init func commonSetup() {
>>> self.y = “My String”
>>> self.z = 4.2
>>> }
>>>
>>> init(x: Int) {
>>> self.x = x
>>> commonSetup() //No error because commonSetup() sets the value of
>>> ‘y’ & ‘z'
>>> super.init()
>>> }
>>> }
>>>
>>> Basically the @init functions would be inlined into the init. They would
>>> only be callable from inits, and could only be called a single time within
>>> each init.
>>>
>>> Thanks,
>>> Jon
>>>
>>>> I believe there was(was?) already a suggestion to introduce special methods
>>>> that could be called from initializers. IMO this is a better solution to
>>>> the problem as you really should not call 'usual' instance method until the
>>>> instance is fully instantiated(super.init() called in your case):
>>>>
>>>> class MyClass : MySuperClass {
>>>>
>>>> let x : Int
>>>> let y : String //let!
>>>>
>>>> initfunc calcY(somePatam: Int) -> String {
>>>> return ....
>>>> }
>>>>
>>>> init(x: Int) {
>>>> self.x = x
>>>> self.y = assignY(5)
>>>> super.init()
>>>> }
>>>> }
>>>
>>>
>>>
>>> _______________________________________________
>>> swift-evolution mailing list
>>> swift-evolution at swift.org
>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>>
>>
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
More information about the swift-evolution
mailing list