본문 바로가기

Go/[Go]Up Down Counting 게임 만들기

Up Down Counting Game 키보드 입력하기(정수값 입력하기)

Up Down Counting 게임을 시작하기 앞서 사용자가 키보드에 어떻게 입력할지에 대해 설명하겠습니다.

 

user input

위 그림은 사용자가 input을 어떻게 하게될지에 대해 보여주는 결과물입니다.

 

위 그림과 같이 입력하기 위해 어떻게 코드를 구성해야할지 결과부터 보여드리겠습니다.

fmt.Print("사용자 추측 숫자 : ")
reader := bufio.NewReader(os.Stdin)
input, err := reader.ReadString('\n')
if err != nil {
	log.Fatal(err)
}
input = strings.TrimSpace(input)
userNum, err := strconv.Atoi(input)
if err != nil {
	log.Fatal(err)
}

해당 코드를 분석해보겠습니다.

실제 코드로 구현하기 위한 패키지

import(
    "fmt" // print를 위한 패키지
    "os" // os.Stdin을 위한 패키지
    "bufio" // Reader를 가져오기 위한 패키지
    "strings" // input값에 '\n'을 없애기 위한 패키지. -> strings.TrimSpace
    "log" // 에러 처리를 위한 패키지
    "strconv" // string을 int형으로 변환하기 위한 패키지
)

 

reader := bufio.NewReader(os.Stdin)

NewReader(file)은
io.Reader 인터페이스로 io.Reader 인터페이스 따르는 읽기 인스턴스 생성합니다.

 

input, err := reader.ReadString('\n')

reader.ReadString('\n')은 os.Stdin 파일로 부터 '\n'이라는 룬(rune)을 만나기 전까지의 string 값을 읽어오는 작업을 수행합니다. 즉, 키보드로부터 입력받은 값에 Enter 키 값을 입력 받기 전까지의 모든 값들을 받을 수 있게 합니다.

이때, ReadString()이라는 함수는 다중 반환값을 가집니다.
정상적으로 입력값이 들어오게 된다면 input에 해당 값을 저장하게되고, 
비정상적인 입력값이 들어오게 된다면 err에 에러값을 반환하게 됩니다.

정상적인 값이라면 err은 nil이라는 값을 갖습니다.
비정상적인 값이라면 err에 에러 메시지를 담아 저장하게 됩니다.

그러나 Go 언어는 변수를 선언하였다면, 반드시 사용해야합니다. 사용하지 않게 되면 컴파일 에러가 발생하기 때문입니다. 따라서, ReadString() 함수를 사용하게 된다면 반드시 에러 처리 문구를 작성해야합니다.

따라서 예시 코드와 같이 if문으로 예외처리를 하였습니다.
if err !=nil{
	log.Fatal(err)
}​

(nil이란 Zero Value를 의미합니다.)

+a : 입력값에 대한 예외처리를 할 필요가 없는 경우엔 아래와 같이 처리하여도 정상적으로 동작할 것입니다.

input, _ := reader.ReadString('\n')

위와 같이 빈 식별자에 값을 할당하게 된다면 정상적으로 동작할 것입니다.
그 이유는 무엇일까요?
-> 빈 식별자에 값을 할당하면 그 값은 버려지게 되고, Go 언어는 빈 식별자를 변수로 취급하지 않기 때문입니다.

 

1. input := strings.TrimSpace(input)
2. userNum, err := strconv.Atoi(input)

strings.TrimSpace() 함수는 처음과 끝에 존재하는 '\n', '\t', ' '와 같은 모든 공백문자를 제거해주는 기능입니다.
따라서 입력한 값 중 Enter 키 값인 \n를 제거해주는 기능을 수행합니다.

이후 strconv.Atoi(input)을 통해 string 값을 int 값으로 변환시켜줍니다.
이때, 해당 함수 또한 다중 반환값이기 때문에 반드시 2번과 같이 배치시켜야합니다.
error 값을 포함하므로 if err != nil 조건문을 이용하여 에러 처리문을 만들어줍니다.

하지만, 한 가지 의문이 들 수 있습니다. Go 언어는 다중 선언이 불가능한 것으로 알고있는데, 어떻게 해당 예시 코드처럼 err 라는 변수를 2번이나 선언할 수 있었던걸까요?

그 이유는 단축 변수 선언(:=)의 특징 때문입니다.

단축 변수 선언은 기존에 선언한 변수를 똑같이 선언한다하더라도, 다중 변수 선언한 변수 중 단 한개라도 새로운 변수를 선언하게 된다면 컴파일 에러 없이 정상적으로 동작합니다.
한 번에 이해하기 힘들기 때문에 예를 들어 설명하겠습니다.

a, b := 2, 3
c, b := 4, 5
초기 a, b := 2, 3의 의미는 a와 b라는 새로운 변수를 선언하고 2와 3이라는 값을 할당하는 것입니다.
이후, 두 번째 c, b := 4, 5의 의미는 c라는 새로운 변수를 선언하여 4를 할당하고 b라는 기존의 값에 5를 할당한다는 것입니다.

a, b := 2, 3
a, b := 4, 5
그러나, 이와 같은 예시는 정상적으로 동작하지 않을 것입니다.

즉, 다중 변수를 선언할 때 단 한개라도 새로운 변수를 선언하게 된다면 코드는 정상적으로 동작하게 된다는 사실을 인지하고 계시면 좋습니다. 이와 같은 기능이 있는 이유는 Go 언어는 수 많은 함수가 여러 개의 값을 반환하기 때문입니다. 따라서 변수를 재사용하기 위해 이와 같은 기능은 필수라고 생각합니다.