Reputation: 337
Swift's way to create a red button:
let button: UIButton = {
let button = UIButton()
button.backgroundColor = .red
return button
}()
With my extension (kotlin's approach):
let button: UIButton = UIButton().apply(){ this in
this.backgroundColor = UIColor.red
}
There are two problems with my extension, first one is that Xcode doesn't recognize the closure parameter "this", it shows << error type >>, so I don't have autocomplete (although it's working), and the second one is that I would like to be able to infer the generic type since I'm already instantiating it.
The extension:
extension NSObject {
func apply<T>(_ closure: (T) -> ()) -> T {
let this = self as! T
closure(this)
return this
}
}
I hope someone can find a solution for this. Thanks in advance.
Upvotes: 1
Views: 394
Reputation: 274835
The problem here is that Swift cannot infer the type of T
. You did not and cannot tell Swift to use the current type as the type of the closure. Self
is only available in the result type of methods in a class.
You can do something like this:
func apply<T>(_ obj: T, closure: (T) -> Void) -> T {
closure(obj)
return obj
}
apply(UIButton()) { this in this.backgroundColor = .red }
but I don't think that's what you want. You want the word apply
to be in the middle, right?
Unfortunately, I cannot think of how you would achieve that. As an alternative, you can try replacing the word "apply" with an operator. For example, I think -->
is quite suitable for this.
infix operator -->
func --> <T>(obj: T, closure: (T) -> Void) -> T {
closure(obj)
return obj
}
let button = UIButton() --> { this in this.backgroundColor = .red }
Upvotes: 1
Reputation: 149
I'm not sure why it's not working for you. If the extension is inside a class put it outside of the class so it's on its own. If that is how it is already try clearing the errors with the command (command + k), this will reload them. If the error remains it's very confusing because it is working fine for me.
Upvotes: 0