4 ms·
Mutating and non-mutating Swift contexts
- bartvk 5y agoWhat I find crazy in this context, is the following: struct ToggleExample: View { @State private var isWarningEnabled = false var body: some View { VStack { Text("Hello, world!") .foregroundColor(self.isWarningEnabled ? .red : .primary) Button(action: { self.isWarningEnabled.toggle() }, label: { Text("Hit me to toggle") }) } } } As you notice, the button action is a closure. In this case, a single line. Thus, I would expect that the following shorter code would work: Button(action: self.isWarningEnabled.toggle) { Text("Hit me to toggle") } That fails however with the following error message: Partial application of 'mutating' method is not allowed In a sense, this is logical. The `toggle()` is `mutating` and if we'd be able to save it as a closure, then we could run it from anywhere. That's like a reference value, when we're actually talking about a struct. But with SwiftUI, we're already in this gray area.
- tempodox 5y agoI think you misunderstood. The `action` closure is invoked with no arguments, but the invocation `self.isWarningEnabled.toggle()` does pass one argument, namely the `self` value from the closure's lexical context (`.toggle()` needs to know which instance to manipulate). If you replace the no-argument closure with a function that expects one argument (`self.isWarningEnabled.toggle`), you get the partial application the error mentions (“partial application” is passing fewer arguments to a function than it expects).
- bartvk 5y agoAha, of course... much appreciated, the penny dropped!
- willyt 5y agoI don’t write swift, but didn’t you miss a comma and a label for your Text(“Hit me to toggle”) argument in your second example? Did you mean: Button(action: self.isWarningEnabled.toggle, label:{ Text("Hit me to toggle") }) Not sure if you can just pass the method signature and omit the parentheses so it doesn’t get called like you can in python. Would be interested to know.
- deergomoo 5y ago> I don’t write swift, but didn’t you miss a comma and a label Swift has a feature called "trailing closures". If the last argument to a function is a closure, you can close the brackets early and put the closure directly after.
- andrekandre 5y agoSwift’s concept of structured mutations only applies to value types, not to reference types like classes and actors. i feel like this would be even more usefull for classes.... it would great if classes could be read-only by default and you had to specify clearly what operations was able to mutate it... but perhaps that would make working with classes more cumbersome...
- Shadonototro 5y agoSwift is such a nice language to work with, and SwiftUI puts to shame everything both Windows/Android has to offer, it's not even close.. minus xcode of course...
- myko 5y agoI mostly agree re: the language itself but Compose is a lot more production ready than SwiftUI, unless you're only targeting iOS 14+, or really 15+ SwiftUI has horrendous bugs in each . release of iOS 13 and 14 has plenty of them too. It really needs to be deployed a la Jetpack Compose on Android, being tied to the OS makes it very difficult to ship reliable code using it.