create account

[The Go Programming Language] 1장 튜토리얼 - 1.2 커맨드라인 인수 by modolee

View this thread on: hive.blogpeakd.comecency.com
· @modolee ·
$0.09
[The Go Programming Language] 1장 튜토리얼 - 1.2 커맨드라인 인수
![modolee_logo](https://steemitimages.com/DQmWQDjyP5d1RNW3mkCWUkDQ6yh3uDJFUZErPpaKBwKi4gM/iron_modolee.png)
안녕하세요. 개발자 모도리입니다.
**[The Go Programming Language](https://www.gopl.io/)** 라는 책으로 Go를 공부하고 있으며, 해당 책의 내용을 요약 정리해서 올리려고 합니다. 저는 [번역본](http://www.aladin.co.kr/shop/wproduct.aspx?ItemId=76703559)을 구매해서 공부하고 있습니다.

### 지난 게시물
* [[Go] Mac에서 Atom으로 Go 개발 환경 구축하기](https://steemit.com/kr-dev/@modolee/go-mac-atom-go)
* [[The Go Programming Language] 1장 튜토리얼 - 1.1 Hello, World](https://steemit.com/kr-dev/@modolee/the-go-programming-language-1-hello-world)

---

# 1장 튜토리얼
## 1.2 커맨드라인 인수(Arguments)
* 프로그램이 데이터를 입력 방법 중 하나는 커맨드라인의 인수로 데이터를 받는 방법입니다.
* Go에서는 os 패키지의 Args 변수(os.Args)를 통해서 커맨드라인 인수에 접근할 수 있습니다.
* `os.Args`는 문자열의 슬라이스인데, 기본 개념은 문자열 배열과 비슷하다고 생각하시면 됩니다.
	> **슬라이스 관련 명령**
	* `s[i]` : s의 **i** 번째 원소
	* `s[m:n]` : s의 **m** 번째 원소부터 **n-1** 번째 원소까지의 집합
	* `s[m:]` : s의 **m**번째 원소부터 마지막 원소까지의 집합
	* `s[:n]` : s의 첫번째 원소부터 **n**번째 원소까지의 집합
	* `len(s)` : s가 포함하는 **원소의 개수**

* `os.Args`의 첫번째 요소인 `os.Args[0]`는 명령 자체의 이름입니다.
* 그 외의 요소들은 명령어 이후의 커맨드라인에 인수로 들어온 값들입니다.

### echo 명령 구현 1
* 커맨드라인의 인수를 한 줄로 출력하는 유닉스 echo 명령의 구현
```
// echo1은 커맨드라인 인수를 출력합니다.
package main

import (
	"fmt"
	"os"
)

func main() {
	var s, sep string
	for i := 1; i < len(os.Args); i++ {
		s += sep + os.Args[i]
		sep = " "
	}
	fmt.Println(s)
}
```
*예제코드 [ch1/echo1.go]*
> **실행결과**
> $ go run ch1/echo1.go hi hello bye seeya
>  hi hello bye seeya

* **주석 (line 1)**
  * 주석은 `//`로 시작합니다.
  * main 패키지의 주석은 전체 프로그램을 설명하는 하나 이상의 완전한 문장입니다.
* **import (line 4 ~ 7)**
  * 두 개의 패키지를 단독 import 선언들 대신 괄호로 묶인 선언으로 import합니다. 아래과 동일한 표현입니다.
  ```
  import "fmt"
  import "os"
  ```
  * 임포트의 순서는 중요하지 않는데, 그 이유는 gofmt 도구가 패키지명을 알파벳순으로 정렬해 주기 때문입니다. 아래과 같이 코드를 작성해도 저장할 때 자동으로 알파벳으로 정렬됩니다.
  ```
  import (
	  "os"
	  "fmt"
  )
  ```
* **변수 선언 (line 10 ~ 11)**
  * var 선언은 `s, sep` 두 변수를 문자열 타입으로 선언합니다.
  * 변수는 선언 중에 초기화 할 수 있습니다.
  * 명시적으로 초기화되지 않은 경우에는 암시적으로 해당 타입의 zero value로 초기화 됩니다. (숫자형 변수의 zero value는 `0`, 문자형 변수의 zero value는 `""` )
  * 따라서 *예제코드 [ch1/echo1.go]*에서는 `s, sep`는 모두 빈 문자열(`""`)으로 초기화 됩니다.
  * 루프 인덱스로 사용되는 변수 `i` 는 `:=` 기호로 선언되어 있는데, 이것은 하나 이상의 변수를 선언하고 초기화 값을 할당하는 짧은 변수 선언 방법입니다.
* **증가 구문 (line 11)**
  * `i++` 는 `i`에 1을 더하는 구문입니다. `i += 1`, `i = i + 1` 과 같습니다.
  * 반대로 `i--`는 1을 빼는 구문입니다.
   * 대부분의 C 계열의 언어와 달리 표현식(expressions)이 아닌 문장(statements)이기 때문에 `j = i++`는 허용되지 않으며, 후치 연산자(postfix)만 허용하기 때문에 `++i`도 허용되지 않습니다.
* **반복문 (line 11)**
  * Go의 유일한 루프는 for 문입니다.
  * 3가지 형태로 사용할 수 있습니다.
  ```
  // 가장 기본적인 for 루프
  // 초기화; 조건; 후처리 를 괄호로 묶지 않습니다.
  for 초기화; 조건; 후처리 {
    // 0개 이상의 구문
  }
  
  // while 루프 대체
  for 조건 {
    // . . .
  }
  
  // 무한 루프
  for {
    // . . .
  }
  ```
* **연산자 (line 12)**
  * 숫자에 일반적인 산술 연산자와 논리 연산자를 제공합니다.
  * 문자열의 경우 `+` 연산자는 두 값을 결합합니다.
  ```
  sep + os.Args[i] // 문자열 sep와 os.Args[i]의 결합을 나타냅니다.
  s += sep + os.Args[i] // s의 이전 값에 sep와 os.Args[i]를 연결하고, 이를 다시 s에 할당합니다.
  s = s + sep + os.Args[i] // 위와 동일합니다.
  ```

### echo 명령 구현 2
* echo1과 동일하나 for 루프 범위를 슬라이스로 표현
```
// echo2은 커맨드라인 인수를 출력합니다.
package main

import (
	"fmt"
	"os"
)

func main() {
	var s, sep string
	for _, arg := range os.Args[1:] {
		s += sep + arg
		sep = " "
	}
	fmt.Println(s)
}
```
*예제코드 [ch1/echo2.go]*
* **for 루프 범위 설정 (line 11)**
* `range`는 루프의 각 반복에서 값의 쌍(**index, index에 있는 원소의 값**) 을 생성합니다.
* for 루프를 돌면서 변수 `arg`에 `os.Args`의 index 1의 원소 값 부터 마지막 원소 값까지 할당합니다.
* *예제코드 [ch1/echo2.go]*에서는 index를 사용하지 않지만, range 문의 문법상 index를 처리해야 합니다.
* 그 방법으로 `_`(밑줄)로 표기되는 빈 식별자를 사용하면 됩니다.
> **다양한 변수 선언 및 초기화 방법**
> `s := ""` // 가장 간결하지만, 패키지 수준 변수가 아닌 함수 안에서만 사용할 수 있습니다.
> `var s string` // 문자열의 기본 초기 값에 의존하는 형식입니다.
> `var s = ""` // 여러 변수를 선언하는 경우 외에는 거의 사용 되지 않습니다.
> `var s string = ""` // 변수의 타입과 초기 값의 타입이 다른 경우에 사용합니다.
> 주로 앞의 두 가지 방법 중 하나를 사용합니다.

### echo 명령 구현 3
* echo1, 2는 루프의 반복마다 문자열 `s`는 완전히 새로운 값을 갖습니다.
* `+=`문은 기존 문자열, 공백 문자, 다음 인자를 경합한 새로운 문자열을 생성하고 `s`에 할당합니다.
* `s`의 이전 값은 더 이상 사용되지 않으므로 이후 가비지 컬렉션 될 것입니다.
* 관련 데이터의 양이 큰 경우 이 방식은 비용이 많이 들기 때문에, strings 패키지의 `Join`함수를 사용해서 echo3를 구현해 보겠습니다.
```
package main

import (
  "fmt"
  "os"
  "strings"
)

func main() {
  fmt.Println(strings.Join(os.Args[1:], " "))
}
```
*예제코드 [ch1/echo3.go]*

### 디버깅 용
* 형식에 상관 없이 값만 보려 할 때는 Println이 알아서 결과를 포매팅하게 할 수 있습니다.
```
package main

import (
	"fmt"
	"os"
)

func main() {
	fmt.Println(os.Args[1:])
}
```
*예제코드 [ch1/echo_debug.go]*
> **실행결과**
> $ go run ch1/echo_debug.go hi hello bye seeya
>  [hi hello bye seeya]
👍  ,
properties (23)
authormodolee
permlinkthe-go-programming-language-1-1-2
categorykr-dev
json_metadata{"tags":["kr-dev","kr","go","golang","go-tutorial"],"image":["https://steemitimages.com/DQmWQDjyP5d1RNW3mkCWUkDQ6yh3uDJFUZErPpaKBwKi4gM/iron_modolee.png"],"links":["https://www.gopl.io/","http://www.aladin.co.kr/shop/wproduct.aspx?ItemId=76703559","https://steemit.com/kr-dev/@modolee/go-mac-atom-go","https://steemit.com/kr-dev/@modolee/the-go-programming-language-1-hello-world"],"app":"steemit/0.1","format":"markdown"}
created2018-09-23 05:13:51
last_update2018-09-23 05:13:51
depth0
children1
last_payout2018-09-30 05:13:51
cashout_time1969-12-31 23:59:59
total_payout_value0.068 HBD
curator_payout_value0.021 HBD
pending_payout_value0.000 HBD
promoted0.000 HBD
body_length4,432
author_reputation285,192,678,959
root_title"[The Go Programming Language] 1장 튜토리얼 - 1.2 커맨드라인 인수"
beneficiaries[]
max_accepted_payout1,000,000.000 HBD
percent_hbd10,000
post_id72,006,354
net_rshares66,380,479,512
author_curate_reward""
vote details (2)
@modolee ·
이어보기
[[The Go Programming Language] 1장 튜토리얼 - 1.3 중복 줄 찾기](https://steemit.com/kr-dev/@modolee/the-go-programming-language-1-1-3)
properties (22)
authormodolee
permlinkre-modolee-the-go-programming-language-1-1-2-20181002t062039295z
categorykr-dev
json_metadata{"tags":["kr-dev"],"links":["https://steemit.com/kr-dev/@modolee/the-go-programming-language-1-1-3"],"app":"steemit/0.1"}
created2018-10-02 06:20:39
last_update2018-10-02 06:20:39
depth1
children0
last_payout2018-10-09 06:20:39
cashout_time1969-12-31 23:59:59
total_payout_value0.000 HBD
curator_payout_value0.000 HBD
pending_payout_value0.000 HBD
promoted0.000 HBD
body_length129
author_reputation285,192,678,959
root_title"[The Go Programming Language] 1장 튜토리얼 - 1.2 커맨드라인 인수"
beneficiaries[]
max_accepted_payout1,000,000.000 HBD
percent_hbd10,000
post_id72,460,288
net_rshares0