Can I pattern match based on the presence of an associated value?

Suppose I have:

enum Shape {
    case circle(color: Int)
    case square(color: Int)
    case triangle(color: Int)
    // Many others with color!
    case group
}

func print_color(s: Shape) {
    switch s {
    case .circle(color: let c):
        print("has color \(c)!")
    case .square(color: let c):
        print("has color \(c)!")
    case .triangle(color: let c):
        print("has color \(c)!")
    // Many others and lots of repeated code.
    case .group:
        break
    }
}

I want something like the following, so I don't have to write out each case:

func print_color(s: Shape) {
    switch s {
    case _(color: let c):
        print("has color \(c)!")
    case .group:
        break
    }
}

Is there a way to do this? (a) without changing the Shape type, and (b) with changing the Shape type.

You have a couple of options. Without changing the type:

func print_color(s: Shape) {
    switch s {
    case .circle(color: let c), .square(color: let c), .triangle(color: let c):
        print("has color \(c)!")
    // Many others and lots of repeated code.
    case .group:
        break
    }
}

With changing the type:

enum Shape {
    case circle, square, triangle
}

// this is just a strawman name
enum Drawable {
    case shape(Shape, color: Int)
    case group
}

func print_color(d: Drawable) {
    switch d {
    case .shape(_, color: let c):
        print("has color \(c)!")
    case .group:
        break
    }
}
2 Likes

Thanks @anandabits. I guess there isn't a way to avoid code proportional to the number of enum cases, without changing the type.

There's a dirty way to extract the value:

func print_color(s: Shape) {
	guard s != .group else { return }

	let mirror = Mirror(reflecting: s)
	assert(mirror.displayStyle == .enum)

	guard let value = mirror.children.first?.value else { return }

	withUnsafeBytes(of: value) { ptr in
		let color = ptr.bindMemory(to: Int.self)[0]
		print("has color \(color)!")
	}
}

print_color(s: .square(color: 1234567)) // prints 'has color 1234567!'
1 Like

I appreciate the filth :slight_smile:

3 Likes
Terms of Service

Privacy Policy

Cookie Policy