0

我已经阅读了 Swift 中可用的扩展,想知道是否支持静态protocol extensions?我知道实例方法可以在protocol extension.

我想为我的存储库创建一个协议,以及该存储库的实现:

存储库协议

public protocol NoteRepositoryProtocol {
    func getAllNotes() -> [Note]
}

存储库实现

class NoteRepository : NoteRepositoryProtocol {
    func getAllNotes() -> [Note] {
        return [Note]()
    }
}

然后为了在我的应用程序中保持松散耦合,我想通过工厂创建存储库。我试图变得聪明,并将静态方法附加到我的协议中,如下所示:

public extension NoteRepositoryProtocol {
    public static func createInstance() -> NoteRepositoryProtocol {
        return NoteRepository()
    }
}

我知道如果我把static关键字放在这里可以做到这一点,但我真的希望它是静态的,所以我可以这样做:

func test_note_repository_returns_a_valid_note_repository() {
    let repository = NoteRepositoryProtocol.createInstance()
}

现在,当我想更改我的存储库实现时,我可以通过更新我的协议扩展工厂方法来做到这一点。另一种选择是创建一个实际的工厂来处理这个问题,但我喜欢类型本身存在工厂方法的想法。

当我编译这个时,我得到以下编译器错误:

由于信号而命令失败:非法指令:4

警告:不可变值“存储库”的初始化从未使用过;考虑用赋值替换'_'或删除它 let repository = NoteRepositoryProtocol.createInstance() ~~~~^~~~~~~~~~ _ not existential UNREACHABLE 在 /Library/Caches/com.apple.xbs/ 执行来源/swiftlang/swiftlang-700.0.38.1/src/swift/lib/SILGen/SILGenExpr.cpp:3311!0 swift 0x0000000106760e0b llvm::sys::PrintStackTrace(__sFILE*) + 43 1 swift 0x000000010676154b SignalHandler(int) + 379 2 libsystem_platform.dylib 0x00007fff9440ef1a _sigtramp + 26 3 swift 0x0000000106d5aa2e FirstTarget + 60550 4 swift 0x0000000106761346 abort + 22 5 swift 0x000000010671ae21 llvm: :llvm_unreachable_internal(char const*,

你不能在协议扩展中使用静态方法吗?

更新

我删除了单元测试断言以改善示例源中的问题根源。问题是编译器不喜欢我在协议上调用静态方法。

4

2 回答 2

1

非可选永远不能为零

public static func createInstance() -> NoteRepositoryProtocol? {
    return NoteRepository()
}
于 2015-06-20T08:54:38.840 回答
0

Apple 文档中所述:

协议本身实际上并不实现任何功能。尽管如此,您创建的任何协议都将成为在您的代码中使用的成熟类型。

因此,您不能直接调用协议的静态方法。

于 2016-11-22T12:22:17.860 回答