[swift-evolution] Proposal: Allow #if to guard switch case clauses
Joe Groff
jgroff at apple.com
Wed May 10 13:44:57 CDT 2017
Seems reasonable to me.
> On May 10, 2017, at 1:32 AM, rintaro ishizaki via swift-evolution <swift-evolution at swift.org> wrote:
>
> Hi evolution community,
>
> This proposal allows you to enclose switch cases with #if directive.
> Implementation: 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-4196
>
> Thanks!
> Rintaro
>
>
> Allow #if to guard switch case clauses
>
> • Proposal: SE-NNNN
> • Authors: Rintaro Ishziaki
> • Review Manager: TBD
> • Status: Awaiting review
> Introduction
>
> This proposal adds ability to guard switch case clauses with #if directives.
>
> Swift-evolution thread: Not yet
>
> 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.
>
> 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
>
> }
> }
>
> 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
>
> }
>
>
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
More information about the swift-evolution
mailing list