Expression and Statement
Expressions are evaluated and thus can be reduced to a single value
Statements are executed. Statements are basic building blocks of a program.
위의 두 문장은 간결하게 expression과 statement의 차이를 표현합니다.
다음과 같이 도식화하여 기억하면 좋을 것 같습니다.
Expression - evaluated
Statement - executed
Dart의 공식문서에서 위의 용어를 사용하는 예시를 살펴보겠습니다.
Example in Dart
Switch statements
A switch statement evaluates a value expression against a series of cases. Each case clause is a pattern for the value to match against.
You can use any kind of pattern for a case.
When the value matches a case’s pattern, the case body executes. Non-empty case clauses jump to the end of the switch after completion.
They do not require a break statement. Other valid ways to end a non-empty case clause are a continue, throw, or return statement.
Use a ‘default’ of wildcard _ to execute code when no case clause matches.
Switch 구문에 대해서 설명하는 글입니다.
statement와 expression을 명확하게 구분하여 사용하고 있는것을 볼 수 있습니다.
statement(위의 경우 case body)는 execute(실행)되며 expression(위의 경우 a value)은 evaluate 되는것으로 명확하게 구분짓습니다.
예제를 보며 어떤 부분이 statement이고 어떤 부분이 expression이 되는지를 확인해 보겠습니다.
// 이 문장을 하나의 statement라고 볼 수 있습니다. command 라는 식별자에 'OPEN' 을 할당하라는 명령을 수행합니다.
//한편 'OPEN'은 'OPEN'이라는 값 자체로 evaluated 되었다고 생각하면 expression이라고 볼 수 있습니다.
var command = 'OPEN'; //
// switch statement입니다. switch statement 안에서는 command가 각 case 와의 비교를 통해 어떤 함수가 실행될지를 정하게 됩니다.
// 각각의 case들('CLOSED', 'PENDING', 'APPROVED', 'DENIED', 'OPEN')은
// command와 마찬가지로 expression으로 볼 수 있습니다.
// command가 case 일 경우 실행되는 각각의 함수들(executeClosed, executePending, executeApproved,
// executeDenied, executeOpen, executeUnknown)은
// statement로 볼 수 있습니다.
switch (command) {
case 'CLOSED': // 'CLOSED' is a expression
executeClosed(); // statement
case 'PENDING': // 'PENDING' is a expression
executePending(); // statement
case 'APPROVED': // 'APPROVED' is a expression
executeApproved(); // statement
case 'DENIED': // 'DENIED' is a expression
executeDenied(); // statement
case 'OPEN': // 'OPEN' is a expression
executeOpen(); // statement
default:
executeUnknown(); // statement
}
Switch expression
Dart에서는 Switch를 statement뿐만 아니라 expression으로도 사용이 가능합니다.
switch control flow 를 사용하여 가독성 있게 코드를 짤 수 있습니다.
공식 문서의 설명부터 살펴보겠습니다.
A switch expression produces a value based on the expression body of whichever case matches.
You can use a switch expression wherever Dart allows expressions, except at the start of an expression statement1.
The syntax of a switch expression differs from switch statement syntax.
- Cases do not start with the case keyword.
- A case body is a single expression instead of a series of statements
- Each case must have a body; there is no implicit fallthrough for empty cases.
- Case patterns are separated from their bodies using => instead of :
- Cases are separated by , (and an optional trailing , is allowed)
- Default cases can only use , instead of allowing both default and .
switch statement와 문법적인 차이와 기능적인 차이가 몇 가지 있습니다.
문법적인 차이
- 각각의 case 구분 시 case 키워드를 사용하지 않습니다.
- 각 case의 실행문 부분에 하나의 statement만 들어갈 수 있습니다.
- : 대신 => 을 사용합니다.
- 각각의 케이스들을 comma(,) 을 이용해 구분합니다.
- switch statement의 경우 default, wildcard 를 둘 다 사용할 수 있지만 expression으로 사용 할 경우 wildcard만 사용할 수 있습니다.
기능적인 차이
- switch statement의 경우 case에 body가 없는 것이 허용됩니다. fallthrough 즉 다음케이스로 flow가 자연스럽게 넘어갑니다. 하지만 switch expression으로 사용할 경우 이 기능이 제한됩니다.
Dart에서 switch expression은 expression이 들어갈 수 있는 자리라면 어디든 들어갈 수 있지만 예외적으로 expression statement의 시작부분에는 사용하지 않습니다.
expression statement의 시작부분에 switch문을 사용하고자 한다면 expression이 아니라 statement를 사용하는 것이 훨씬 자연스럽습니다.
switch expression의 사용 예제를 보겠습니다.
// token 변수에 switch statement를 사용해 값을 할당하는 코드입니다.
// 각 case의 body들이 하나의 statement만으로 이루어져있으며 fallthorough 기능을 활용하고 있지 않습니다.
// 각 case의 body들의 statement 부분에 코드가 중복되어 작성되어 있습니다. (token = ...)
// state expression 을 이용해 좀 더 가독성 있는 코드로 바꿀 수 있을 것 같습니다.
switch (charCode) {
case slash || star || plus || minus: // Logical-or pattern
token = operator(charCode);
case comma || semicolon: // Logical-or pattern
token = punctuation(charCode);
case >= digit0 && <= digit9: // Relational and logical-and patterns
token = number();
default:
throw FormatException('Invalid format');
}
// 각 case들이 comma(,)로 구분되며 각 case의 body에서 실행되는 statement들을 한눈에 볼 수 있습니다.
// 하나의 값으로 evaluate되어 token에 값을 할당해줍니다.
token = switch (charCode) {
slash || star || plus || minus => operator(charCode),
comma || semicolon => punctuation(charCode),
>= digit0 && <= digit9 => number(),
_ => throw FormatException('Invalid format');
};
[1]: An expression statement is an expression used in a place where a statement is expected. The expression is evaluated and its result is discarded. Therefore it only makes sense only for expressions that make side effects, such as executing a function or updating a variable.: information_source: