Creating a one-step object and initializing properties in Swift?

Is there a way to assign property values ​​to an instance of a class, 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" }; 

Notification for student2 I can still assign values ​​during initialization, even if there is no constructor in the class.

I could not find in the documentation if you can do something similar 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 because I can add a bunch of instances to the array without explicitly creating variables for each student instance, for example:

 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?

+6
source share
5 answers

You have several options, depending on how you want to configure this type and which syntax is most convenient for you.

You can define a convenient initializer that accepts the properties that you want to set. Useful if you constantly set the same properties, less useful if you set an inconsistent set of additional 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 can define a convenience initializer that takes a block to configure a new instance.

 extension Student { convenience init(_ configure: (Student) -> Void ) { self.init() configure(self) } } Student( { $0.firstName = "Any"; $0.lastName = "Body" } ) 

You can imitate Ruby tap as an extension so that you can work with the object in the middle of the method chain.

 extension Student { func tap(block: (Student) -> Void) -> Self { block(self) return self } } Student().tap({ $0.firstName = "Any"; $0.lastName = "body"}) 

If the latter is useful, you might want to accept tap for any object. I don't think you can do this 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"}) 
+8
source

If your class does not have the required initializer, you can use the closure method to set Student properties before returning a new Student object as follows:

 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 
+4
source

I was looking for this, so I can add a bunch of instances to the array without explicitly creating variables for each instance of the instance [.]

I am not familiar with C #, but in Swift you can do this by simply initializing the objects inside the array declaration:

 var list: [Student] = [ Student(firstName: "John", lastName: "Doe"), Student(firstName: "Jane", lastName: "Jones"), Student(firstName: "Jason", lastName: "Smith") ] 

The other approaches suggested are equally valid, but if you are just trying to fill an array without declaring any variables, Swift makes this easy.

+1
source

I just wanted to point out that if your structure can be immutable, you can just use a struct , not a class , and you will get an implicit initializer for free:

Just paste this into the playing field and change the structure to a class and you will see what I mean.

 struct Student { var firstName : String? var lastName : String? } var student = Student(firstName: "Dan", lastName: "Beaulieu") 
+1
source

This is just syntax candy, but I use a custom operator for this:

  infix operator <- { associativity right precedence 90 } func <-<T:AnyObject>(var left:T, right:(T)->()) -> T { right(left) return left } let rgbButtons:[UIButton] = [ UIButton() <- { $0.backgroundColor = UIColor.redColor() }, UIButton() <- { $0.backgroundColor = UIColor.greenColor() }, UIButton() <- { $0.backgroundColor = UIColor.blueColor() } ] 
+1
source

All Articles