Powerful Concurrency Language Go
저번 시간에는 고 언어의 for, if에 대해서 알아보았습니다. 이번 시간에는 switch, defer에 대해서 학습을 해볼 예정입니다. 일단 앞서 설명드렸듯이, 고 언어는 C언어와 유사한 점이 많다고 말씀드렸습니다. 그 이유로는 많은 이유가 존재하지만, C언어 프로젝트에 참여했던 개발자가 고 언어의 개발에 참여했기 때문일까요? 글쎄요.. 여하튼 고 언어는 현대적 프로그래밍 패러다임이 잘 융화된 언어입니다. C언어를 모티브 했다고 해도 과언은 아닌 게 문법상 일치되는 문법이 많기 때문입니다!
Switch
switch구문은 연속적인 if-else 구문의 또 다른 모습이라고 봐도 무방합니다. 물론 자유도 측면에서는 if-else구문이 더 높을지는 모르나, 여하튼 비슷하다는 것이죠. 아래는 switch-case구문의 문법입니다.
switch <*condition_state> {
case <*condition_val>:
case <*condition_val>:
...
default:
...
}
위 코드의 문법을 따릅니다. 많은 언어들이 switch-case구문과 비슷한 문법들이 존재하기 때문에 적응상 어렵다거나 그럴일은 절대 없다는 거죠. 간략하게 고 언어의 switch구문은 switch 뒤로 오는 모든 케이스를 실행하는 것이 아니라, 선택된 케이스만을 실행한다는 점은 다른 언어들과 비슷합니다. 컴파일 타임에서의 어느 정도 최적화 과정이라고 보면 될 것 같네요. 다른 언어들 같은 경우는 아시다시피, 케이스 문 내부에 break구문이 필요하다는 점은 모두 알고 계실 겁니다. 그러나 고 언어에서는 자동으로 선택된 케이스 구문이 동작하고 마무리 지을 때 break 됩니다. 또한 다른 언어들과 다르게 swtich-case구문의 조건문이 반드시 상수일 필요는 없습니다. 또한 케이스의 조건 변수 또한 마찬가지겠죠? 아래 예제 코드를 보도록 하겠습니다.
package main
import (
"fmt"
)
func add(foo int) int {
return foo + 2
}
func main() {
fmt.Print("어떤 케이스로 들어갈까요?")
switch foo := add(2); foo {
case 4:
fmt.Println(" First Case")
case 2:
fmt.Println(" Second Case")
default:
// freebsd, openbsd,
// plan9, windows...
fmt.Println("Default")
}
}
또한 고 언어의 Switch-case는 각 케이스에 대한 평가 순서가 존재합니다. 그러니까 하나의 케이스라도 성공하게 되면 바로 해당 케이스 구문의 코드를 실행시키고 break된다는 이런 말입니다. 그리고 조건이 없는 Switch구문도 존재합니다. 그러니까 단순 비교가 가능하다는 그런 말이죠,
package main
import (
"fmt"
)
func add2(foo int) int {
return foo + 10
}
func main() {
foo := add2(11)
switch {
case foo < 20:
fmt.Println("Under 20")
case foo > 20:
fmt.Println("Over 20")
default:
fmt.Println("Nil")
}
}
위와 같이 단순 비교도 됩니다. if-else구문과 다를 바가 없죠? 간단하게 사용할 때는 그냥 위와 같이 조건문 없는 switch도 고려해보세요!
Defer
defer 같은 경우에는 스크립트 쪽에서 몇번 봤던 키워드인데, 여기서 잠깐 짚고 넘어가자면, defer의 뜻은 보통 연기하다 라는 의미를 가집니다. 그렇다면 연기하다는 것은 어떤 걸 연기하는 걸까요? 그러니까 상식적으로 생각해볼 때, defer 키워드가 앞에 착 붙어버리면 그 뒤에 오는 평가식들은 어떠한 시점을 넘어 연기된 다음 동작한다라는 거겠죠? 문법은 아래와 같습니다.
defer <*evaluation*>
defer구문이 속해있는 함수의 범위가 종료될 때 까지 defer구문은 동작하지 않습니다. 아이러니하게도 컴파일러는 defer구문을 만나는 그 즉시 평가를 하게 되지만, 함수 호출 자체는 defer구문을 둘러싼 함수가 종료될 때까지 동작하지 않다가 종료될 때 동작합니다. 아래의 코드와 같이 말이죠
package main
import "fmt"
func foofoo(){
fmt.Println("EndPoint")
}
func main() {
fmt.Println("Start Point")
defer foofoo()
fmt.Println("Not a Start Point")
}
defer는 마치 스택의 형태로 동작합니다. 스택 자료구조에 대해서 잘 모르시는 분이라면 제 스택 자료구조 글을 읽고 오시는 것을 추천드립니다.
python과 C++으로 모두 작성되어 있기 때문에 편한 언어를 보시면 될 것 같습니다. 여하튼 스택 자료구조는 후입 선출(LAST IN, FIRST OUT)의 구조를 지닙니다. 맨 마지막 들어온 친구가 맨 먼저 나간다는 거죠. 아래 코드를 보면 명확히 이해할 수 있습니다.
package main
import "fmt"
func main() {
fmt.Println("Stack Start")
for i := 0; i < 10; i++ {
defer fmt.Println(i)
}
fmt.Println("Here Stack")
}
원래대로의 반복문 구조라면 0부터 출력되는 것이 맞습니다. 하지만 위 코드를 동작해보시면 아시겠지만, 9부터 출력됩니다. 그렇다는 말은 즉슨, 맨 마지막에 들어간 데이터부터 나오는 것만 보아도 스택의 형태로 구현되었다는 것을 알 수 있습니다.
이제 고 언어의 아주 기본적인 예제에 대해서는 학습을 끝마쳤습니다. 이제 앞으로 설명드릴 내용들은 조금 더 어려운 내용들이 많습니다. 저 또한 관련 서적을 통해서 학습하고 있지만, 정말 C언어와 유사한 점이 많다는 생각이 드는 언어네요 ㅎㅎㅎ
글 읽어주셔서 감사합니다!
댓글로 피드백, 문의, 질문 모두 환영합니다 !! 😆😆😆😆😆😆
감사합니다!!😊😊😊😊😊😊
다음 강좌 ------>
'Go' 카테고리의 다른 글
[Go#7] Go언어 배열(Array_Slice, by Literal) 문법! (0) | 2021.01.27 |
---|---|
[Go#6] Go언어 pointer, struct 문법!!! (0) | 2021.01.14 |
[Go#4] Go언어 For, if_(반복문, 제어문) 이해하기!!! (0) | 2021.01.07 |
[Go#3] Go언어 패키지, import-export, function 이해하기!!! (0) | 2021.01.05 |
[Go#2] Go언어 변수_ 상수, 타입, 타입 캐스팅!!! (0) | 2021.01.03 |
댓글