Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

315
Views
Why does Swift disallow assignment to self in class init, but not in protocol init?

I often find myself liking how, in the initializers for structs, enums, and protocols, I can write something like self = someValue. This is great when I have some predefined values or am cloning an existing value.

However, this syntax doesn't work for classes. I can't really figure out why, either.

Cannot assign to value: 'self' is immutable

If the concern is double-initialization, the Swift compiler knows if, when, and where I call designated super or self initializers, so it knows whether I'm done initializing this instance. If the concern is that I haven't yet called a designated initializer, then it should be fine because I'd just be making this instance a reference to the other one (2 vars 1 pointer). If the concern is that concurrent access might have caused self to already be initialized... well that's nonsense because we're in the initializer and Swift initializers are not susceptible to that.

And after all that I discovered I can get around this with a single-use protocol:

class MyClass {
    let content: String
    
    init(content: String) {
        self.content = content
    }

    convenience init(from1 other: MyClass) {
        self = other // Cannot assign to value: 'self' is immutable
    }
}



protocol MyProto {}

extension MyClass: MyProto {}



extension MyProto {
    
    init(from2 other: Self) {
        self = other
    }
}



let foo = MyClass(content: "Foo")

print(MyClass(from1: foo)) // Never would've compiled in the first place
print(MyClass(from2: foo)) // Perfectly OK!

So why is this denied in common usage, but allowed in protocol-extensions?

over 4 years ago · Santiago Trujillo
2 answers
Answer question

0

It seems this currently behaves as expected.

The whole problem has been discussed on the swift forums: Assigning to Self in Protocol Extensions

The last time this quirk came up in internal discussions, the thought some of us had was that it might be worthwhile to prohibit classes from conforming to protocols with mutating requirements altogether. If you think about it, this makes some amount of sense — it seems like it would be quite hard to write code that can operate on both mutable values and mutable references generically, since the latter do not have value semantics:

var x = y
x.mutatingProtocolRequirement()
// did y change too?

However the discussion sort of fizzled out.

over 4 years ago · Santiago Trujillo Report

0

There is a pitch for this functionality on the Swift Evolution forum:

Allow self = x in class convenience initializers

https://forums.swift.org/t/allow-self-x-in-class-convenience-initializers/15924

The pitch mentions how this syntax already works for struct value types, and in protocol initializers as mentioned in this question:

Swift's own standard library and Foundation overlay hack around this missing functionality by making classes conform to dummy protocols and using protocol extension initializers where necessary to implement this functionality.

The proposal seems to have widespread support, including from Chris Lattner:

+1, long overdue!!

However the pitch has not yet been implemented. Once implemented, it can be reviewed and potentially added to the Swift language.

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!