cham-s
(Chams)
1
Hi, everyone!
I don't if I'm doing this the right way.
When switching on a enum with an associated value represented as an IndexSet, the code crashes at runtime.
import Foundation
enum Action {
case a
case b(IndexSet)
}
func doSomething(_ action: Action) {
switch action {
case .a:
print("Perform logic when a")
case .b(_):
print("Delete entries when b using indexSet")
}
}
doSomething(.a)
But it works perfectly with other types, String or Int for instance.
import Foundation
enum Action {
case a
case b(String)
}
func doSomething(_ action: Action) {
switch action {
case .a:
print("Perform logic when a")
case .b(_):
print("Perform logic when b using String")
}
}
doSomething(.a)
Any pointer would be much appreciated.
1 Like
Avi
2
You've barely scratched the surface of bugginess.
Take the following.
enum E {
case a
// case b(IndexSet)
case c(Int)
}
func moo(e: E) {
switch e {
case .a: print("a")
// case .b: print("b")
case .c: print("c")
}
}
moo(e: .a)
//moo(e: .b(IndexSet()))
moo(e: .c(4))
The output is as-expected:
a
c
Uncomment all references to case b except the call to moo(e: b(IndexSet())) and the output becomes:
a
a // 😱
2 Likes
tkrajacic
(Thomas Krajacic)
3
cham-s
(Chams)
4
Thank you for you answer!
Wow
the double a as output was unexpected.
So the compiler compiler considers case a as the right match even when we explicitly provide case c as input to the function?
So I wasn't doing anything weird then.
Is IndexSet the culprit?
Does it mean I have to find a work around?
Given that I need to use IndexSet inside my enum?
Or maybe I'm completely missing the point.
Avi
5
It appears that the compiler can't handle having IndexSet as an associated value. I just found this manifestation while researching the crash you reported. The crash also reproduces if you uncomment the middle call to moo(e:).
1 Like
cham-s
(Chams)
6
Thanks! I'll make sure to read more about it.
cham-s
(Chams)
7
Oh I see. Thanks again for you clarification.
Temporary workaround indices from the original IndexSet are converted to [Int] then converted back to IndexSet when needed.
import Foundation
enum Action {
case add(Int)
case delete(indices: [Int])
}
func doSomething(on values: inout [Int], action: Action) {
switch action {
case let .add(value):
values.append(value)
case let .delete(indices):
let indexSet = IndexSet(indices)
values.remove(atOffsets: indexSet)
}
}
var values = [1, 2, 3, 4, 5, 6, 7, 8, 9]
doSomething(on: &values, action: .add(10))
let indexSet = IndexSet([2, 3, 4, 7])
let indices: [Int] = indexSet.map { $0 }
doSomething(on: &values, action: .delete(indices: indices))