Is there a way to assign property values to a class instance even if it is not a parameter in the init constructor? For example, in C# I can do this:
public class Student
{
public string firstName;
public string lastName;
}
var student1 = new Student();
var student2 = new Student { firstName = "John", lastName = "Doe" };
Notice for student2
I can still assign values during initialization even though there's no constructor in the class.
I could not find in the documentation if you can do something like this for Swift. If not, is there a way to use extensions
to extend the Student
class to assign property values during initialization?
The reason I'm looking for this is so I can add a bunch of instances to an array without explicitly creating variables for each student instance, like this:
var list = new[] {
new Student { firstName = "John", lastName = "Doe" },
new Student { firstName = "Jane", lastName = "Jones" },
new Student { firstName = "Jason", lastName = "Smith" }
}
Any native or elegant way to achieve this in Swift?
An initializer is a special type of function that is used to create an object of a class or struct. In Swift, we use the init() method to create an initializer. For example, class Wall { ... // create an initializer init() { // perform initialization ... } }
Swift init() Initialization is the process of preparing an instance of a class, structure, or enumeration for use. This process involves setting an initial value for each stored property on that instance and performing any other setup or initialization that is required before the new instance is ready for use.
The init() initializer for Bicycle starts by calling super. init(), which calls the default initializer for the Bicycle class's superclass, Vehicle. This ensures that the numberOfWheels inherited property is initialized by Vehicle before Bicycle has the opportunity to modify the property.
You have a couple of options depending on how you want to configure this type and what syntax is most convenient for you.
You could define a convenient initializer which accepts the properties you want to set. Useful if you're setting the same properties all the time, less useful if you're setting an inconsistent set of optional properties.
public class Student
{
public var firstName:String?;
public var lastName:String?;
}
extension Student {
convenience init(firstName: String, lastName: String) {
self.init()
self.firstName = firstName
self.lastName = lastName
}
}
Student(firstName: "Any", lastName: "Body")
You could define a convenience initializer which accepts a block to configure the new instance.
extension Student {
convenience init(_ configure: (Student) -> Void ) {
self.init()
configure(self)
}
}
Student( { $0.firstName = "Any"; $0.lastName = "Body" } )
You could imitate Ruby's tap
method as an extension so you can operate on an object in the middle of a method chain.
extension Student {
func tap(block: (Student) -> Void) -> Self {
block(self)
return self
}
}
Student().tap({ $0.firstName = "Any"; $0.lastName = "body"})
If that last one is useful you might want to be able to adopt tap
on any object. I don't think you can do that automatically but you can define a default implementation to make it easier:
protocol Tap: AnyObject {}
extension Tap {
func tap(block: (Self) -> Void) -> Self {
block(self)
return self
}
}
extension Student: Tap {}
Student().tap({ $0.firstName = "Any"; $0.lastName = "body"})
If your class has no required initialiser, you can use a closure method to set the Student properties before returning the new Student object as follow:
public class Student {
var firstName = String()
var lastName = String()
}
let student1 = Student()
let student2: Student = {
let student = Student()
student.firstName = "John"
student.lastName = "Doe"
return student
}()
print(student2.firstName) // John
print(student2.lastName) // Doe
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With