列挙型を定義することをプロトコルに要求させることは可能ですか?
//trying to do this
protocol JSONEncodable {
enum PropertyName // Type not allowed here
func valueForProperty(propertyName:PropertyName) -> Any
}
//which would be implemented like this
struct Person : JSONEncodable {
var firstName : String
var lastName : String
enum PropertyName {
case FirstName
case LastName
func allValues() {
return [Person.PropertyName.FirstName, Person.PropertyName.LastName]
}
func stringValue() {
return "\(self)"
}
}
func valueForProperty(propertyName:PropertyName) -> Any {
switch propertyName {
case .FirstName:
return firstName
case .LastName:
return lastName
}
}
}
//so that I could do something like this
extension JSONEncodable {
func JSONObject() -> [String:AnyObject] {
var dictionary = [String:AnyObject]()
for propertyName in PropertyName.allValues {
let value = valueForProperty(propertyName)
if let valueObject = value as? AnyObject {
dictionary[propertyName.stringValue()] = valueObject
}else if let valueObject = value as? JSONEncodable {
dictionary[propertyName.stringValue()] = valueObject.JSONObject()
}
}
return dictionary
}
}
これはSwiftでは不可能です。可能である場合は、どのケースを参照することができないので(どのケースなのかわからないため)、それを直接使用する方法は不明です。最終的にはas
キャストする必要がありますが、これはプロトコルの全体のポイントを壊します。 (enum
がコレクション型である場合の使用を想像するかもしれませんが、そうではなく、それが「コレクション型」を必要とするだけである可能性があります。)
プロトコルはassociatedtypes
を持つことができます。これは、任意のサブクラスで順守する必要があるだけです。
enum MyEnum {
case foo
case bar
}
protocol RequiresEnum {
associatedtype SomeEnumType
func doSomethingWithEnum(someEnumType: SomeEnumType)
}
class MyRequiresEnum: RequiresEnum {
typealias SomeEnumType = MyEnum
func doSomethingWithEnum(someEnumType: SomeEnumType) {
switch someEnumType {
case .foo:
print("foo")
case .bar:
print("bar")
}
}
}
let mre = MyRequiresEnum()
mre.doSomethingWithEnum(.bar)
編集:associatedtype
必須に準拠する
associatedtype
に準拠しているRawRepresentable
を使用してそれを実行できると思います
次に例を示します。
protocol SomeProtocol {
associatedtype SomeType: RawRepresentable
}
たとえば、RawRepresentable
のようなString
のタイプを指定する必要がある場合は、次のようにできます。
protocol SomeProtocol {
associatedtype SomeType: RawRepresentable where SomeType.RawValue: StringProtocol
}
これで、enum
がString
であるRawRepresentable
以外のものでプロトコルを実装しようとすると、コンパイラエラーが発生します。お役に立てば幸いです。