我试图达到这个效果:
enum Foo: Int { case a, b, c, d }
enum Bar: Int { case a, b, c, d }
func generate<T: RawRepresentable>(using index: Int) -> T
{
guard let output = T(rawValue: index) else { preconditionFailure() }
return output
}
但我收到错误:
Playground execution failed: error: GenericEnums.playground:18:24: error: cannot invoke initializer for type 'T' with an argument list of type '(rawValue: Int)'
guard let output = T(rawValue: index) else { preconditionFailure() }
^
GenericEnums.playground:18:24: note: expected an argument list of type '(rawValue: Self.RawValue)'
guard let output = T(rawValue: index) else { preconditionFailure() }
我哪里错了?
答案 0 :(得分:3)
首先,index
不应该是Int
,而应该是T.RawValue
,因为RawRepresentable
协议没有指定RawValue
}&#39; s类型为Int
。其次,如果您不想键入为generate
指定返回值的变量的注释,则应将泛型类型参数T
应用于表示您的类型的输入参数想要生成。
以下是您的通用功能的工作和测试实现。 value
参数必须是您要生成的enum
的类型。
enum Foo: Int { case a, b, c, d }
enum Bar: Int { case a, b, c, d }
func generate<T: RawRepresentable>(value ofClass: T.Type,using index: T.RawValue) -> T {
guard let output = T(rawValue: index) else { preconditionFailure() }
return output
}
//the output of this version needs to be assigned to a type annotated variable,
//otherwise the compiler cannot figure out the exact type that T represents
func generate<T: RawRepresentable>(using index: T.RawValue) -> T {
guard let output = T(rawValue: index) else { preconditionFailure() }
return output
}
generate(value:Foo.self, using: 1) //returns Foo.b
let a: Bar = generate(using: 0) //returns Bar.a
答案 1 :(得分:2)
DávidPásztor的答案是更通用的答案,应该在大多数情况下使用。
但是,如果您只想使用基于Int
的{{1}}类型执行某些操作,
你可以这样做:
RawRepresentable
答案 2 :(得分:0)
我个人认为你过分思考这个问题。如果在提供错误的原始值时目标是崩溃,请执行以下操作:
extension RawRepresentable {
init(rawValueOrDie what:RawValue) {
self.init(rawValue:what)!
}
}