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"})
Jonah source share