Sweeper的回答是好的,但是我看到你在错误处理上付出了一些努力。斯威夫特不擅长帮助你,所以你必须自己扩展。
(
Dictionary
RawRepresentable
来自Swift 1,没有错误。他们从来没有现代化,只是返回可选。)
/// Acts as a dictionary that `throw`s instead of returning optionals.
public protocol valueForKeyThrowingAccessor {
associatedtype Key
/// Should just be a throwing subscript, but those don't exist yet.
func value<Value>(for: Key) throws -> Value
}
/// Acts as a dictionary.
public protocol valueForKeySubscript: valueForKeyThrowingAccessor {
associatedtype Value
subscript(key: Key) -> Value? { get }
}
public extension valueForKeySubscript {
/// - Throws: `KeyValuePairs<Key, Value>.AccessError.noValue`
func value(for key: Key) throws -> Value {
guard let value = self[key]
else { throw KeyValuePairs<Key, Value>.AccessError.noValue(key: key) }
return value
}
/// - Throws: `KeyValuePairs<Key, Value>.AccessError.typeCastFailure`
func value<Value>(for key: Key) throws -> Value {
guard let value = try value(for: key) as? Value
else { throw KeyValuePairs<Key, Value>.AccessError.typeCastFailure(key: key) }
return value
}
}
extension Dictionary: valueForKeySubscript { }
public extension KeyValuePairs {
/// An error throw from trying to access a value for a key.
enum AccessError: Error {
case noValue(key: Key)
case typeCastFailure(key: Key)
}
}
public extension RawRepresentable {
/// Like `init(rawValue:)`, if it was throwing instead of failable.
/// - Throws: `RawRepresentableExtensions<Self>.Error.invalidRawValue`
/// if there is no value of the type that corresponds with the specified raw value.
init(_ rawValue: RawValue) throws {
guard let instance = Self(rawValue: rawValue)
else { throw RawRepresentableExtensions<Self>.Error.invalidRawValue(rawValue) }
self = instance
}
}
/// A namespace for nested types within `RawRepresentable`.
public enum RawRepresentableExtensions<RawRepresentable: Swift.RawRepresentable> {
public enum Error: Swift.Error {
case invalidRawValue(RawRepresentable.RawValue)
}
}
public extension InitializableWithElementSequence where Element: RawRepresentable {
/// - Throws: `RawRepresentableExtensions<Element>.Error.invalidRawValue`
init<RawValues: Sequence>(rawValues: RawValues) throws
where RawValues.Element == Element.RawValue {
self.init(
try rawValues.map(Element.init)
)
}
}
/// A type that can be initialized with a `Sequence` of its `Element`s.
public protocol InitializableWithElementSequence: Sequence {
init<Sequence: Swift.Sequence>(_: Sequence)
where Sequence.Element == Element
}
extension Array: InitializableWithElementSequence { }
extension Set: InitializableWithElementSequence { }
extension InitializableWithElementSequence where Element == Intent {
init(filters: [String: Any]) throws {
try self.init(
rawValues: try filters.value(for: "intent") as [String]
)
}
}
try filters.map(Set.init)