为什么直接引用协议方法时swift不能编译?

时间:2017-08-07 05:29:11

标签: ios swift swift-protocols

给出以下结构:

struct TestStruct {
    func test() {
        print("Something")
    }
}

像这样引用test函数有效:

let testFunc = TestStruct.test // (TestStruct) -> () -> Void

为了执行该功能,您必须执行以下操作:

testFunc(TestStruct())() // Prints "Something"

假设您使TestStruct符合协议:

protocol Test {
    func test()
}

extension TestStruct: Test {}

现在尝试通过这样的协议来引用test函数不起作用:

let testFunc = Test.func // Does not compile, no error message

testFunc (Test) -> () -> Void的类型不应该是router.use('/:id', function(req, res){ console.log("Things " + Date.now()); res.send('Applies to all pages ' + req.params.id); }); router.get('/28', function(req, res){ res.send('Secret 28 page'); }); 吗?为什么现在正在编译?

2 个答案:

答案 0 :(得分:2)

根据docs,您编写的代码旨在在某些时候起作用。他们还没有实现它。

编译器崩溃而不是打印错误这一事实意味着您发现了编译器错误。

:; xcrun swift
Welcome to Apple Swift version 4.0 (swiftlang-900.0.54.10 clang-900.0.31). Type :help for assistance.
  1> struct TestStruct { 
  2.     func test() { 
  3.         print("Something") 
  4.     } 
  5. }
  6> protocol Test { 
  7.     func test() 
  8. } 
  9.  
 10. extension TestStruct: Test {}
 11> let testFunc = Test.test
Segmentation fault: 11

“分段错误:11”表示编译器崩溃。 您应该转到SR-75,如果您没有帐户,请创建一个帐户,然后提交错误报告。

您可以通过将测试代码放入文件并进行编译来查看编译器堆栈跟踪:

:; echo 'protocol Test { func test() }; let testFunc = Test.test' > main.swift && xcrun swiftc main.swift
0  swift                    0x000000010b5efeaa PrintStackTraceSignalHandler(void*) + 42
1  swift                    0x000000010b5ef2e6 SignalHandler(int) + 662
2  libsystem_platform.dylib 0x00007fff9742fb3a _sigtramp + 26
3  libsystem_platform.dylib 0x00007f82e307de00 _sigtramp + 1271194336
4  swift                    0x0000000108818c2c swift::Lowering::SILGenFunction::manageOpaqueValue(swift::Lowering::SILGenFunction::OpaqueValueState&, swift::SILLocation, swift::Lowering::SGFContext) + 188
5  swift                    0x000000010882fa1b swift::ASTVisitor<(anonymous namespace)::RValueEmitter, swift::Lowering::RValue, void, void, void, void, void, swift::Lowering::SGFContext>::visit(swift::Expr*, swift::Lowering::SGFContext) + 11067
6  swift                    0x000000010882d6a1 swift::ASTVisitor<(anonymous namespace)::RValueEmitter, swift::Lowering::RValue, void, void, void, void, void, swift::Lowering::SGFContext>::visit(swift::Expr*, swift::Lowering::SGFContext) + 1985
7  swift                    0x0000000108838f01 swift::ASTVisitor<(anonymous namespace)::RValueEmitter, swift::Lowering::RValue, void, void, void, void, void, swift::Lowering::SGFContext>::visit(swift::Expr*, swift::Lowering::SGFContext) + 49185
8  swift                    0x0000000108849329 void llvm::function_ref<void (swift::Expr*)>::callback_fn<swift::Lowering::RValue swift::Lowering::SILGenFunction::emitOpenExistentialExpr<swift::Lowering::RValue, (anonymous namespace)::RValueEmitter::visitOpenExistentialExpr(swift::OpenExistentialExpr*, swift::Lowering::SGFContext)::$_5>(swift::OpenExistentialExpr*, (anonymous namespace)::RValueEmitter::visitOpenExistentialExpr(swift::OpenExistentialExpr*, swift::Lowering::SGFContext)::$_5)::'lambda'(swift::Expr*)>(long, swift::Expr*) + 41
9  swift                    0x00000001088499e7 swift::Lowering::SILGenFunction::emitOpenExistentialExprImpl(swift::OpenExistentialExpr*, llvm::function_ref<void (swift::Expr*)>) + 1591
10 swift                    0x000000010882e1cb swift::ASTVisitor<(anonymous namespace)::RValueEmitter, swift::Lowering::RValue, void, void, void, void, void, swift::Lowering::SGFContext>::visit(swift::Expr*, swift::Lowering::SGFContext) + 4843
11 swift                    0x000000010882cb74 swift::Lowering::SILGenFunction::emitExprInto(swift::Expr*, swift::Lowering::Initialization*) + 148
12 swift                    0x000000010881ccf6 swift::Lowering::SILGenFunction::emitPatternBinding(swift::PatternBindingDecl*, unsigned int) + 198
13 swift                    0x00000001087ce3cf swift::ASTVisitor<swift::Lowering::SILGenModule, void, void, void, void, void, void>::visit(swift::Decl*) + 559
14 swift                    0x00000001087cd4ab swift::Lowering::SILGenModule::emitSourceFile(swift::SourceFile*, unsigned int) + 1115
15 swift                    0x00000001087cee39 swift::SILModule::constructSIL(swift::ModuleDecl*, swift::SILOptions&, swift::FileUnit*, llvm::Optional<unsigned int>, bool) + 841
16 swift                    0x0000000107f6dedc performCompile(swift::CompilerInstance&, swift::CompilerInvocation&, llvm::ArrayRef<char const*>, int&, swift::FrontendObserver*, swift::UnifiedStatsReporter*) + 13020
17 swift                    0x0000000107f69394 swift::performFrontend(llvm::ArrayRef<char const*>, char const*, void*, swift::FrontendObserver*) + 7332
18 swift                    0x0000000107f1ead8 main + 12248
19 libdyld.dylib            0x00007fff97220235 start + 1
20 libdyld.dylib            0x000000000000000f start + 1759378907
Stack dump:
0.  Program arguments: /Applications/Xcode-beta.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift -frontend -c -primary-file main.swift -target x86_64-apple-macosx10.9 -enable-objc-interop -sdk /Applications/Xcode-beta.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.13.sdk -color-diagnostics -module-name main -o /var/folders/kn/1d839myx4tlghz34f_lh3hvc0000gn/T/main-65ce73.o 
<unknown>:0: error: unable to execute command: Segmentation fault: 11
<unknown>:0: error: compile command failed due to signal 11 (use -v to see invocation)

答案 1 :(得分:0)

您的结构和协议之间的区别在于协议没有实现方法test。它只是声明了一个名为test的方法。表达式TestStruct.test返回对结构的方法test的实现的引用。由于协议没有test的实现,编译器无法返回对此的引用。

注意:协议Test不会知道有关其实现类或结构的任何内容。因此,Test.test无法返回对TestStruct.test的引用。在多个Test实现的情况下,这也是一种暧昧。

结论:您不能参考方法的协议实现,因为它们没有实现。