我已阅读Swift中提供的Extensions,并想知道是否支持静态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() ~~~~ ^ ~~~~~~~~~ _ 不存在 无法执行的执行 /Library/Caches/com.apple.xbs/Sources/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 *,char const *,unsigned int)+ 481 6 swift 0x00000001049b503c swift :: Lowering :: SILGenFunction :: emitOpenExistentialImpl(swift :: OpenExistentialExpr *,llvm :: function_ref)+ 2588 7 swift 0x00000001049c0ba1 swift :: Lowering :: RValue swift :: Lowering :: SILGenFunction :: emitOpenExistential(swift :: OpenExistentialExpr *,(匿名命名空间):: RValueEmitter :: visitOpenExistentialExpr(swift :: OpenExistentialExpr *,swift :: Lowering :: SGFContext):: $ _ 0)+ 65 8 swift 0x00000001049b6f00 swift :: ASTVisitor<(匿名命名空间):: RValueEmitter,swift :: Lowering :: RValue,void,void,void,void,void,swift :: Lowering :: SGFContext> :: visit(swift :: Expr *,swift :: Lowering :: SGFContext)+ 4864 9 swift 0x00000001049af49f swift :: Lowering :: SILGenFunction :: emitExprInto(swift :: Expr *,swift :: Lowering :: Initialization *)+ 303 10 swift 0x00000001049a0dd8 swift :: Lowering :: SILGenFunction :: visitPatternBindingDecl(swift :: PatternBindingDecl *)+ 232 11 swift 0x0000000104a021fa swift :: ASTVisitor<(匿名命名空间):: StmtEmitter,void,void,void,void,void,void> :: visit(swift :: Stmt *)+ 362 12 swift 0x0000000104a02085 swift ::降低:: SILGenFunction :: emitStmt(swift :: Stmt *)+ 21 13 swift 0x00000001049ca136 swift :: Lowering :: SILGenFunction :: emitFunction(swift :: FuncDecl *)+ 390 14 swift 0x000000010496d3ed swift :: Lowering :: SILGenModule :: emitFunction(swift :: FuncDecl *)+ 253 15 swift 0x0000000104a0833c(匿名命名空间):: SILGenType :: emitType()+ 956 16 swift 0x0000000104a07ede swift :: Lowering :: SILGenModule :: visitNominalTypeDecl(swift :: NominalTypeDecl *)+ 30 17 swift 0x000000010497028b swift :: Lowering :: SILGenModule :: emitSourceFile(swift :: SourceFile *,unsigned int)+ 571 18 swift 0x000000010497106f swift :: SILModule :: constructSIL(swift :: ModuleDecl *,swift :: SILOptions&,swift :: FileUnit *,llvm :: Optional,bool,bool)+ 703 19 swift 0x000000010497128b swift :: performSILGeneration(swift :: FileUnit&,swift :: SILOptions&,llvm :: Optional,bool)+ 123 20 swift 0x000000010477a691 performCompile(swift :: CompilerInstance&,swift :: CompilerInvocation&,llvm :: ArrayRef,int&)+ 9153 21 swift 0x00000001047780b3 frontend_main(llvm :: ArrayRef,char const *,void *)+ 2515 22 swift 0x000000010477428f main + 1983 23 libdyld.dylib 0x00007fff934fb5c9 start + 1 24 libdyld.dylib 0x0000000000000048 start + 1823492736
您是否可以在协议扩展中使用静态方法?
我删除了单元测试断言,以改进示例源中问题的根源。问题是编译器不喜欢我在协议上调用静态方法。
答案 0 :(得分:1)
非可选永远不能为零
public static func createInstance() -> NoteRepositoryProtocol? {
return NoteRepository()
}
答案 1 :(得分:0)