[英]How to specialize a generic enum in Swift
I'm using the antitypical/result package to provide a generic Result type. 我正在使用典型/结果包来提供通用的Result类型。 This package defines Result as follows:
该程序包定义结果如下:
public enum Result<T, Error> {
...
}
Now, I only wish to return errors of type NSError
in my code, so it would be nice if I didn't have to keep doing things this: 现在,我只希望在我的代码中返回类型为
NSError
错误,所以如果我不必继续这样做,那就太好了:
func myFunc() -> Result<String, NSError> { ... }
Instead, I want to create a derived StdResult type so that I can do this instead: 相反,我想创建一个派生的StdResult类型,以便可以代替这样做:
func myFunc() -> StdResult<String> { ... }
I've tried various things but I can't find a solution. 我已经尝试过各种方法,但是找不到解决方案。 This, for example, doesn't work:
例如,这不起作用:
typealias StdResult<T> = Result<T, NSError>
Is there a solution which will work? 有没有可行的解决方案?
Unfortunately we're pretty limited here. 不幸的是,我们在这里非常有限。 Swift doesn't support generic typealias, so we can do this as a sort of hack with struct:
Swift不支持通用的typealias,因此我们可以通过struct来实现:
struct StdResult<T> {
typealias Type = Test<T, NSError>
}
func myFunc() -> StdResult<String>.Type {
}
Does that fit what you were looking for closely enough? 这是否足以满足您的需求?
At the moment, there's no generic typealias support nor enumeration inheritance, but you could use RawRepresentable
protocol. 目前,没有通用的类型别名支持或枚举继承,但是您可以使用
RawRepresentable
协议。 It's not as easy as if a generic typealias exists, but it may fit your needs. 这并不像存在通用类型别名那样容易,但是它可能满足您的需求。
From Apple's documentation : 从苹果的文档 :
A type that can be converted to an associated "raw" type, then converted back to produce an instance equivalent to the original.
可以转换为关联的“原始”类型,然后再转换回以生成与原始等效的实例的类型。
public protocol RawRepresentable {
typealias RawValue
public init?(rawValue: Self.RawValue)
public var rawValue: Self.RawValue { get }
}
That said, your raw value must be Result<T, NSError>
: 也就是说,您的原始值必须为
Result<T, NSError>
:
enum StdResult<T>: RawRepresentable {
var rawValue: Result<T, NSError> {
switch self {
case .Success(let value):
return Result.Success(value)
case .Failure(let error):
return Result.Failure(error)
}
}
init?(rawValue: Result<T, NSError>) {
switch rawValue {
case .Success(let value):
self = .Success(value)
case .Failure(let error):
self = .Failure(error)
}
}
case Success(T)
case Failure(NSError)
}
func myFunc() -> StdResult<String> { }
Note : Properties and methods of original Result
enumeration are only accessible from rawValue
property, so, for example, if you want to compare your new StdResult
with another, you must use rawValue
property or reimplement these protocols yourself. 注意 : 只能从
rawValue
属性访问原始Result
枚举的属性和方法,因此,例如,如果要将新的StdResult
与另一个进行比较,则必须使用rawValue
属性或自己重新实现这些协议。
You could alias the specific Result type so you don't have to constantly do func myThing() -> Result<String, NSError>
您可以为特定的Result类型添加别名,这样就不必经常执行
func myThing() -> Result<String, NSError>
eg 例如
typealias StringResult = Result<String, NSError>
func myOtherThing() -> StringResult
It's more difficult for me to come up with a generic solution like 对我来说,想出一个通用的解决方案比较困难
MyResult<String>
without understanding exactly what Result
is doing. 不了解
Result
到底在做什么。 I could take another crack at it if you post some of the internals. 如果您发布一些内部信息,我可能会再三破解。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.