Reputation: 10739
I am having a Protocol implementation as follows.
protocol DatabaseInjectable {
static func deriveObjectFromDBRow(row: [String]) -> Self? // Method - 1
static func collectAllObjectsForDatabaseAction(action: (Database) -> Void) -> [Self]? // Method - 2
}
Where I am successful with the correspondent implementation of Method - 1
like this:
static func deriveObjectFromDBRow(row: [String]) -> Self? {
...
}
But I could not implement the Method - 2
like this:
static func collectAllObjectsForDatabaseAction(action: (WWDatabase) -> Void) -> [Self]? {
...
}
There I am getting an error like this:
'Self' is only available in a protocol or as the result of a method in a class;
Any help to return the array form of Self
(the class it self) would be nice.
Upvotes: 1
Views: 1778
Reputation: 73176
You can make use of a typealias
in your protocol DatabaseInjectable
, and use this as an alias to Self
type in the classes conforming to your protocol.
class Database {
var desc : String = "Default"
}
protocol DatabaseInjectable {
typealias MySelf
static func deriveObjectFromDBRow(row: [String]) -> MySelf?
static func collectAllObjectsForDatabaseAction(action: (Database) -> Void) -> [MySelf]?
}
class MyClass : DatabaseInjectable {
typealias MySelf = MyClass
static func deriveObjectFromDBRow(row: [String]) -> MySelf? {
return MyClass()
}
static func collectAllObjectsForDatabaseAction(action: (Database) -> Void) -> [MySelf]? {
return [MyClass(), MyClass()]
}
}
/* example */
let closure : (Database) -> () = { print($0.desc) }
var arr : [MyClass]? = MyClass.collectAllObjectsForDatabaseAction(closure)
/* [MyClass, MyClass] */
One drawback here is, however, that you could set e.g. typealias MySelf = Int
(in the class) and have your functions return an integer/array of integers (rather than self/[Self]), and still conform to you protocol. Possibly this is a deal-breaker.
Upvotes: 0
Reputation: 274
If you can set your class final
you can replace Self
by the class name
final class SampleClass: DatabaseInjectable {
init() {
}
static func deriveObjectFromDBRow(row: [String]) -> SampleClass? {
return SampleClass()
}
static func collectAllObjectsForDatabaseAction(action: (Database) -> Void) -> [SampleClass]? {
let array = [SampleClass]()
return array
}
}
Upvotes: 1
Reputation: 947
There's a very well written answer here, but in short, you can define your protocol as such:
protocol DatabaseInjectable {
static func deriveObjectFromDBRow(row: [String]) -> DatabaseInjectable? // Method - 1
static func collectAllObjectsForDatabaseAction(action: (Database) -> Void) -> [DatabaseInjectable]? // Method - 2
}
Upvotes: 0