[swift-evolution] [Proposal] Sealed classes by default

Brent Royal-Gordon brent at architechies.com
Sat Jul 2 03:51:23 CDT 2016


> On Jul 2, 2016, at 12:42 AM, L. Mihalkovic <laurent.mihalkovic at gmail.com> wrote:
> 
> This is a situation I often run into in jave where I would use an enum to create a finite set of constants to be passed (say action identifers). But then this makes it very difficult for external modules to extend the core set of actions locally. So i generally windup with an enum and an interface (the enum implements the interface).

Sure. I would argue that that's the exact right approach to take for this kind of thing. For instance, for storyboard segue identifiers, I would write something like this:

	open protocol SegueIdentifierProtocol: RawRepresentable where RawValue == String {}

	open protocol SeguePerformable {
		associatedtype SegueIdentifier: SegueIdentifierProtocol
		
		// Hooks
		func shouldPerformSegue(with identifier: SegueIdentifier, sender: AnyObject?) -> Bool
		func prepare(for segue: UIStoryboardSegue, with identifier: SegueIdentifier, sender: AnyObject?)
	}

	public extension SeguePerformable where Self: UIViewController {
		// Machinery to bridge to normal UIViewController API
		
		func performSegue(with identifier: SegueIdentifier, sender: AnyObject?) {...}
		override func shouldPerformSegue(withIdentifier identifier: String, sender: AnyObject?) -> Bool {...}
		override func prepare(for segue: UIStoryboardSegue, sender: AnyObject?) {...}
	}

Rather than attempting some sort of universal enum of all identifiers:

	extension UIViewController {
		open enum SegueIdentifier: String {
			// Extensible for users
		}
		
		// Hooks
		open func shouldPerformSegue(with identifier: SegueIdentifier, sender: AnyObject?) -> Bool {...}
		open func prepare(for segue: UIStoryboardSegue, with identifier: SegueIdentifier, sender: AnyObject?) {...}
		
		// Machinery to bridge to normal UIViewController API
		public func performSegue(with identifier: SegueIdentifier, sender: AnyObject?) {...}
		override public func shouldPerformSegue(withIdentifier identifier: String, sender: AnyObject?) -> Bool {...}
		override public func prepare(for segue: UIStoryboardSegue, sender: AnyObject?) {...}
	}

> Then local extensions are free to define their own local enums to cover only their local extensions to the original core set of actions. Then the public api definition constrains the action parameter to be enum&TheRequiredInterface.

Okay, but why constrain it to `enum`? Do you actually care that it's an `enum`, or do you just care that there's a type which can give you the identifier you need? If somebody wrote a highly dynamic client of your code that needed to generate identifiers on the fly, why should your code reject that?

-- 
Brent Royal-Gordon
Architechies



More information about the swift-evolution mailing list