[swift-evolution] [Idea] Set variables to "_" in two-stage init; remove IUO

Jonathan Hull jhull at gbis.com
Thu Jun 16 06:27:13 CDT 2016


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



More information about the swift-evolution mailing list