我正試圖在使用泛型的Swift 3中完成面向協議的編程。這還沒有完全支持嗎?我會告訴你我想在下面做什麼,但不會編譯。我在這裏錯過了什麼嗎?我的目標是能夠使用面向協議的編程來執行依賴注入,以便在單元測試中輕鬆地模擬這些結構。是否有可能將通用協議傳遞給Swift 3中正確的依賴注入構造函數?
protocol ZombieServiceProtocol {
func fetchZombies()
var zombieRepository: RepositoryProtocol<Zombie> { get set }
}
struct ZombieService: ZombieServiceProtocol {
var zombieRepository: RepositoryProtocol<Zombie>
init(zombieRepository: RepositoryProtocol<Zombie>) {
self.zombieRepository = zombieRepository
}
func fetchZombies() {
self.zombieRepository.deleteAll()
self.createFakeZombies()
}
private func createFakeZombies() {
for index in 1...100 {
let zombie = Zombie(id: index, name: "Zombie \(index)")
self.zombieRepository.insert(zombie)
}
}
}
殭屍類看起來是這樣的:
public struct Zombie: Persistable {
var id: Int
let name: String?
init(id: Int, name: String?) {
self.id = id
self.name =name
}
}
它的持久化協議看起來是這樣的:
protocol Persistable {
var id: Int { get set }
}
而且我的倉庫代碼看起來是這樣的:
protocol RepositoryProtocol: class {
associatedtype Object: Persistable
//...
func insert(_ object: Object) -> Void
func deleteAll(_ predicate: (Object) throws -> Bool) -> Void
}
class Repository<Object: Persistable>: RepositoryProtocol {
var items = Array<Object>()
//...
func insert(_ object: Object) {
self.items.append(object)
}
func deleteAll() {
self.items.removeAll()
}
}
我得到了followi NG錯誤在我ZombieServiceProtocol:
- 不能專注非泛型類型 'RepositoryProtocol'
我得到了我的ZombieService以下錯誤:
- 不能專注非泛型類型「RepositoryProtocol '
- 成員'insert'不能用於協議類型的值 'RepositoryProtocol';使用一個通用的約束,而不是
,並強調正是我試圖完成,這裏是一個簡單的測試是什麼樣子的,我創建一個模擬庫,並嘗試使用,而不是在一個真正的我的ZombieService:
@testable import ZombieInjection
class ZombieServiceTests: XCTestCase {
private var zombieRepository: RepositoryProtocol<Zombie>!
private var zombieService: ZombieServiceProtocol
override func setUp() {
super.setUp()
// Put setup code here. This method is called before the invocation of each test method in the class.
self.zombieRepository = RepositoryMock<Zombie>()
self.zombieService = ZombieService(zombieRepository: self.zombieRepository)
}
override func tearDown() {
// Put teardown code here. This method is called after the invocation of each test method in the class.
super.tearDown()
}
func testExample() {
// Arrange
// Act
self.zombieService.fetchZombies()
// Assert
XCTAssert(self.zombieRepository.count() > 0)
}
}
此代碼也不會與上述相同的錯誤進行編譯。
我一直在尋找associatedTypes和typeAlias標籤以及Generics Manifesto。在看「宣言」時,我認爲這屬於「通用協議」部分,該部分目前標記爲「不太可能」(這是令人沮喪的)。如果我無法完成上述的嘗試,那麼下一個最佳解決方案是什麼?
看起來像是一個響亮的否?去嘗試和重構,看看我還能做些什麼... – PkL728