[swift-evolution] Proposal: Allow #if to guard switch case clauses
Kevin Nattinger
swift at nattinger.net
Wed May 10 12:49:40 CDT 2017
I support this proposal 100%. In fact, I just ran into this use case.
I’d support extending it to allow partial-case coverage (as long as it doesn’t cross a case: boundary, obviously), e.g.
switch result {
case .success(let object):
doSomething(with: object)
case .error(let error):
#if debug
alertUser(error)
#endif
handleError(error)
}
I don’t see a reason to prevent that, but if we can just get the current proposal (full cases only) in Swift 4 I’ll be satisfied and just put this on my (large and growing) list of things to bring up for 5.
> On May 10, 2017, at 6:28 AM, rintaro ishizaki via swift-evolution <swift-evolution at swift.org> wrote:
>
> Here's proposal link:
> https://github.com/rintaro/swift-evolution/blob/conditional-switch-case/proposals/NNNN-conditional-switch-case.md <https://github.com/rintaro/swift-evolution/blob/conditional-switch-case/proposals/NNNN-conditional-switch-case.md>
>
> Fixed some typos, including my name :)
>
> 2017-05-10 17:32 GMT+09:00 rintaro ishizaki <fs.output at gmail.com <mailto:fs.output at gmail.com>>:
> Hi evolution community,
>
> This proposal allows you to enclose switch cases with #if directive.
> Implementation: https://github.com/apple/swift/pull/9457 <https://github.com/apple/swift/pull/9457>
> This is one of the oldest SR issue:
> https://bugs.swift.org/browse/SR-2 <https://bugs.swift.org/browse/SR-2>
> https://bugs.swift.org/browse/SR-4196 <https://bugs.swift.org/browse/SR-4196>
>
> Thanks!
> Rintaro
>
>
> Allow #if to guard switch case clauses
>
> Proposal: SE-NNNN <https://gist.github.com/rintaro/NNNN-filename.md>
> Authors: Rintaro Ishziaki <https://github.com/rintaro>
> Review Manager: TBD
> Status: Awaiting review
> <https://gist.github.com/rintaro/a5a9d9836027d7df7a5326a3a8cf9d89#introduction>Introduction
>
> This proposal adds ability to guard switch case clauses with #if directives.
>
> Swift-evolution thread: Not yet <https://lists.swift.org/pipermail/swift-evolution/>
> <https://gist.github.com/rintaro/a5a9d9836027d7df7a5326a3a8cf9d89#motivation>Motivation
>
> When you want to switch cases only for certain compilation condition, say switching #if os(Linux) guarded enum cases, right now you have to write switch twice:
>
> enum Operation {
> case output(String)
> #if os(Linux)
> case syscall(Syscall)
> #endif
> }
>
> func execute(operation: Operation) {
> #if !os(Linux)
> switch operation {
> case .output(let str):
> print(str)
> }
> #else
> switch operation {
> case .output(let str):
> print(str)
> case .syscall(let call):
> call.execute()
> }
> #endif
> }
> This is annoying and error prone.
>
> <https://gist.github.com/rintaro/a5a9d9836027d7df7a5326a3a8cf9d89#proposed-solution>Proposed solution
>
> This proposal allows #if to guard switch case clauses.
>
> func execute(operation: Operation) {
> switch operation {
> case .output(let str):
> print(str)
> #if os(Linux)
> case .syscall(let call):
> call.execute()
> #endif
> }
> }
> <https://gist.github.com/rintaro/a5a9d9836027d7df7a5326a3a8cf9d89#detailed-design>Detailed design
>
> This change shouldn't affect existing #if directives within case clauses. This code should works as expected:
>
> func foo(x: MyEnum) {
> switch x {
> case .some(let str):
> doSomething(str)
> #if PRINT_SOME
> print(str)
> #endif
> case .other:
> doOther()
> }
> }
> Only if the next token after #if is case or default, the Parser treat it as guarding case clauses.
>
> func foo(x: MyEnum) {
> switch x {
> case .some(let str):
> doSomething(str)
> #if HAS_OTHER
> case .other:
> doOther()
> }
> #endif
> }
> func foo(x: MyEnum) {
> switch x {
> case .some(let str):
> doSomething(str)
> #if HAS_OTHER
> default:
> break
> #endif
> }
> Error cases:
>
> switch x {
> case .some(let str):
> doSomething(str)
> #if HAS_OTHER
> case .other:
> doOther()
> #else
> doMore() // error: all statements inside a switch must be covered by a 'case' or 'default'
> #endif
> }
> switch x {
> case .some(let str):
> doSomething(str)
> #if HAS_OTHER
> doMore()
> case .other:
> doOther() // error: 'case' label can only appear inside a 'switch' statement
> #else
> }
> You can guard multiple cases as long as it is guarding whole clauses:
>
> switch x {
> case .some(let str):
> doSomething(str)
> #if HAS_OTHERS
> case .other:
> doOther()
> case .more:
> doMore()
> #else
> }
>
> <https://gist.github.com/rintaro/a5a9d9836027d7df7a5326a3a8cf9d89#source-compatibility>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20170510/b94e722e/attachment.html>
More information about the swift-evolution
mailing list