On May 10, 2017, at 1:32 AM, rintaro ishizaki via swift-evolution <swift-evolution@swift.org> wrote:
Hi evolution community,
This proposal allows you to enclose switch cases with if directive.
Implementation: [Parse] Allow #if to guard switch case clauses by rintaro · Pull Request #9457 · apple/swift · GitHub
This is one of the oldest SR issue:
[SR-2] Build configuration directives can not wrap switch cases · Issue #42628 · apple/swift · GitHub
[SR-4196] Allow #if (conditional compilation) to guard switch cases · Issue #46779 · apple/swift · GitHub
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@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution