我最近编写了一个函数和一些相关代码,它们充当一种切换表达式(按预期工作)和posted it on CodeReview.SE
我已经开始尝试改进自己的代码并且似乎已经碰壁了,因为看起来我的代码会使操场挂起并且在放入项目时也不会编译。但是,当在项目中输入所有内容时,Xcode不会抱怨,直到我真正尝试构建它。这就是我所拥有的:
func caze<T: Equatable, R>(vals: T..., @autoclosure(escaping) ret f: () -> R) -> (AnySequence<T>, () -> R) {
return (AnySequence(vals), f)
}
func caze<T, R where T: Equatable, T: ForwardIndexType>(range: Range<T>, @autoclosure(escaping) ret f: () -> R) -> (AnySequence<T>, () -> R) {
return (AnySequence(range), f)
}
func schwitch<T: Equatable, R>(value: T, _ cases: (AnySequence<T>, () -> R)..., @autoclosure def: () throws -> R) rethrows -> R {
for (vals, f) in cases {
if vals.contains(value) {
return f()
}
}
return try def()
}
func test() {
schwitch(5,
caze(0, ret: "hello"),
caze(1, 2, ret: "test"),
caze(3..<7, ret: "lol"),
def: "nop")
schwitch("helloo",
caze("hello", "Hello", ret: "test"),
def: "nop")
}
这是我在尝试构建项目时遇到的错误:
命令因信号失败:分段错误:11
堆栈跟踪:
0 swift 0x000000010c7f366b llvm::sys::PrintStackTrace(llvm::raw_ostream&) + 43
1 swift 0x000000010c7f2956 llvm::sys::RunSignalHandlers() + 70
2 swift 0x000000010c7f3ccf SignalHandler(int) + 287
3 libsystem_platform.dylib 0x00007fff87f0752a _sigtramp + 26
4 libsystem_platform.dylib 0x00007f82f4bf0418 _sigtramp + 1825476360
5 swift 0x000000010ab9e994 (anonymous namespace)::ApplyClassifier::classifyRethrowsArgument(swift::Expr*, swift::Type) + 52
6 swift 0x000000010ab9ea2b (anonymous namespace)::ApplyClassifier::classifyRethrowsArgument(swift::Expr*, swift::Type) + 203
7 swift 0x000000010ab9f02a (anonymous namespace)::ApplyClassifier::classifyRethrowsArgument(swift::Expr*, swift::Type) + 1738
8 swift 0x000000010ab9e56c (anonymous namespace)::ApplyClassifier::classifyApply(swift::ApplyExpr*) + 652
9 swift 0x000000010ab9dc86 (anonymous namespace)::ErrorHandlingWalker<(anonymous namespace)::CheckErrorCoverage>::walkToExprPre(swift::Expr*) + 278
10 swift 0x000000010ac45854 swift::ASTVisitor<(anonymous namespace)::Traversal, swift::Expr*, swift::Stmt*, bool, swift::Pattern*, bool, void>::visit(swift::Stmt*) + 148
11 swift 0x000000010ac42ef7 swift::Stmt::walk(swift::ASTWalker&) + 87
12 swift 0x000000010ab9d9d5 swift::TypeChecker::checkFunctionErrorHandling(swift::AbstractFunctionDecl*) + 405
13 swift 0x000000010ab7ef1b typeCheckFunctionsAndExternalDecls(swift::TypeChecker&) + 1451
14 swift 0x000000010ab7f665 swift::performTypeChecking(swift::SourceFile&, swift::TopLevelContext&, swift::OptionSet<swift::TypeCheckingFlags, unsigned int>, unsigned int) + 1765
15 swift 0x000000010aa00eb4 swift::CompilerInstance::performSema() + 4580
16 swift 0x000000010a543596 performCompile(swift::CompilerInstance&, swift::CompilerInvocation&, llvm::ArrayRef<char const*>, int&) + 934
17 swift 0x000000010a54268d frontend_main(llvm::ArrayRef<char const*>, char const*, void*) + 2781
18 swift 0x000000010a53e0ac main + 1932
19 libdyld.dylib 0x00007fff912a35ad start + 1
问题似乎是使用该功能,因为如果我遗漏那部分,一切编译都很好。仅使用caze
似乎也可以正常工作,因为以下工作也可以正常工作:
caze(5, ret: "hello")
let test: (AnySequence<Int>, () -> String) = caze(0...5, ret: "hello") // Swift needs some help figuring out which function to use here
这只是Swift编译器中的一个错误,还是我遗漏了什么?
答案 0 :(得分:1)
首先:正如布莱恩已经说过的那样,它肯定是一个编译器错误,应该从不崩溃。
解决问题:根本原因似乎是rethrows
,因为使用以下编译并运行没有任何问题。这与堆栈跟踪5 - 7 classifyRethrowsArgument
匹配。
func schwitch<T: Equatable, R>(value: T, cas cases: (AnySequence<T>, () -> R)..., @autoclosure def: () -> R) -> R {
for (vals, f) in cases {
if vals.contains(value) {
return f()
}
}
return def()
}
同样适用于
func schwitch<T: Equatable, R>(value: T, cas cases: (AnySequence<T>, () -> R)..., @autoclosure def: () throws -> R) -> R {
for (vals, f) in cases {
if vals.contains(value) {
return f()
}
}
return try! def()
}
我知道这个事实远非一个完整的答案,但我想至少给出一些我发现的暗示。如果您不需要默认情况下能够抛出此代码应该适合您。我将试图弄清楚rethrows
导致问题的原因。
swift编译器的TypeCheckError.cpp
可能有助于解决这个问题。