> One of the things that surprised me is that there still isn’t concise syntax
> for creating option sets, a pattern I see out in the wild a fair bit. While
> Swift 2 did introduce OptionSetType for structs, it still feels somewhat
> obtuse and non-obvious. It would be great if we could something like:
>
> options NotSoSecretVariations {
> case ProteinStyle,
> case AnimalStyle,
> case GrilledOnions,
> ...
> }
>
> That said, I have a feeling this isn’t the first time the Swift team has come
> across a pitch like this. If this really is unfeasible, it would be great
> and really educational to hear what the challenges are.
Personally, what I'd like to see is the concept of an option separated from
that of an option *set*. Once you do that, you can define an individual option
simply using an enum, and let the set handle combining the options together.
Here's what I mean. Take an Objective-C NS_OPTIONS enum:
typedef NS_OPTIONS(NSUInteger, NSStringCompareOptions) {
NSCaseInsensitiveSearch = 1,
NSLiteralSearch = 2, /* Exact character-by-character
equivalence */
NSBackwardsSearch = 4, /* Search from end of source
string */
NSAnchoredSearch = 8, /* Search is limited to start
(or end, if NSBackwardsSearch) of source string */
NSNumericSearch = 64, /* Added in 10.2; Numbers
within strings are compared using numeric value, that is, Foo2.txt < Foo7.txt <
Foo25.txt; only applies to compare methods, not find */
NSDiacriticInsensitiveSearch NS_ENUM_AVAILABLE(10_5, 2_0) = 128, /*
If specified, ignores diacritics (o-umlaut == o) */
NSWidthInsensitiveSearch NS_ENUM_AVAILABLE(10_5, 2_0) = 256, /* If
specified, ignores width differences ('a' == UFF41) */
NSForcedOrderingSearch NS_ENUM_AVAILABLE(10_5, 2_0) = 512, /* If
specified, comparisons are forced to return either NSOrderedAscending or
NSOrderedDescending if the strings are equivalent but not strictly equal, for
stability when sorting (e.g. "aaa" > "AAA" with NSCaseInsensitiveSearch
specified) */
NSRegularExpressionSearch NS_ENUM_AVAILABLE(10_7, 3_2) = 1024 /*
Applies to rangeOfString:..., stringByReplacingOccurrencesOfString:..., and
replaceOccurrencesOfString:... methods only; the search string is treated as an
ICU-compatible regular expression; if set, no other options can apply except
NSCaseInsensitiveSearch and NSAnchoredSearch */
};
I think this should be translated to Swift like this:
enum NSStringCompareOption: Int {
case CaseInsensitiveSearch = 0 // Because 1 << 0 == 1
case LiteralSearch = 1 // 1 << 1 == 2
case BackwardsSearch = 2
case AnchoredSearch = 3
case NumericSearch = 6 // 1 << 6 == 64
case DiacriticInsensitiveSearch = 7
case WidthInsensitiveSearch = 8
case ForcedOrderingSearch = 9
case RegularExpressionSearch = 10
}
Meanwhile, a method taking NSStringCompareOptions like this:
- (NSComparisonResult)compare:(NSString *)string
options:(NSStringCompareOptions)mask;
Should be translated as:
func compare(string: NSString, options mask:
OptionSet<NSStringCompareOption>) -> NSComparisonResult
OptionSet would be a generic type like this:
struct OptionSet<Option: RawRepresentable where Option.RawValue:
IntegerType>: SetAlgebraType, RawRepresentable {
typealias Element = Option
typealias RawValue = Option.RawValue
...
}
This definition should work for any NS_OPTIONS where the options are
non-overlapping. I'm not sure if that's *every* option set in the Apple
frameworks, but I think it's the vast majority of them. (The incompatible ones
could use the existing mechanism.) And to create your own option set, all you
have to do is write an enum with an integer raw type that has less than 32 or
64 cases, depending on your target. You don't even have to specify the raw
values—the default ones will work fine.
--
Brent Royal-Gordon
Architechies
_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution