[Go 언어] 19. Go언어에서는 비교 연산자를 사용하는 곳이 많아요.

안녕하세요. 언제나 휴일, 언휴예요.

이번에는 값의 크기를 비교하는 비교 연산자를 알아보기로 해요. 비교 연산자는 같음(==), 다름(!=), 작음(<), 작거나 같음(<=), 큼(>), 크거나 같음(>=) 연산이 있어요.

C언어와 C++언어에서는 비교 연산을 문자열에 사용할 수 없고 배열에서는 개발자가 생각하는 결과와 다르게 메모리 주소를 비교했어요. 하지만 Go 언어에서는 문자열이나 배열에서 비교할 수 있고 비교 결과도 우리가 생각하는 것과 차이가 없어요.

이번 게시글에서는 배열에서 비교하는 연산은 다루지 않을 거예요.

새 프로젝트를 생성하여 비교 연산자를 사용하는 표현을 사용해 봅시다.

[그림 1] LiteIDE에서 새 프로젝트 생성 및 소스 파일 추가
    var i1, i2, i3 int = 2, 2, 3
    fmt.Println(i1, "==", i2, " 결과", i1 == i2)
    fmt.Println(i1, "==", i3, " 결과", i1 == i3)
   
    var f1, f2, f3 float32 = 0.1, 0.1, 0.2
    fmt.Println(f1, "==", f2, " 결과", f1 == f2)
    fmt.Println(f1, "==", f3, " 결과", f1 == f3)
   
    var s1, s2, s3 string = "abc", "abc", "ABC"
    fmt.Println(s1, "==", s2, " 결과", s1 == s2)
    fmt.Println(s1, "==", s3, " 결과", s1 == s3)
   
    var hs1, hs2, hs3 string = "강감찬", "강감찬", "홍길동"
    fmt.Println(hs1, "==", hs2, " 결과", hs1 == hs2)
    fmt.Println(hs1, "==", hs3, " 결과", hs1 == hs3)

비교 연산은 생각하는 것과 차이가 없어요. 다음은 두 개의 정수 사이에 같음(==) 연산을 사용한 표현이예요.

  • 정수 사이에 같음(==) 연산
    var i1, i2, i3 int = 2, 2, 3
    fmt.Println(i1, "==", i2, " 결과", i1 == i2)
    fmt.Println(i1, "==", i3, " 결과", i1 == i3)

결과는 여러분의 생각과 같아요.

2 == 2 결과 true
2 == 3 결과 false

다음은 두 개의 실수 사이에 같음(==) 연산을 사용한 표현이예요.

  • 실수 사이에 같음(==) 연산
    var f1, f2, f3 float32 = 0.1, 0.1, 0.2
    fmt.Println(f1, "==", f2, " 결과", f1 == f2)
    fmt.Println(f1, "==", f3, " 결과", f1 == f3)

결과는 여러분의 생각과 같아요.

0.1 == 0.1 결과 true
0.1 == 0.2 결과 false

다음은 두 개의 문자열 사이에 같음(==) 연산을 사용한 표현이예요. 문자열 비교는 길이를 비교하는 것이 아니라 사전식 비교입니다. 사전식 비교는 앞의 문자부터 비교하다가 차이가 있는 부분을 만나면 해당 위치의 문자의 크기를 비교하는 것이예요. Go 언어에서는 아스키 코드값으로 사전식 비교를 수행합니다.

  • 문자열 사이에 같음(==) 연산
    var s1, s2, s3 string = "abc", "abc", "ABC"
    fmt.Println(s1, "==", s2, " 결과", s1 == s2)
    fmt.Println(s1, "==", s3, " 결과", s1 == s3)

결과는 다음과 같습니다.

abc == abc 결과 true
abc == ABC 결과 false

다음은 한글로 구성한 문자열 사이에 같음(==) 연산을 사용한 표현이예요.

  • 한글로 구성한 문자열 사이에 같음(==) 연산
    var hs1, hs2, hs3 string = "강감찬", "강감찬", "홍길동"
    fmt.Println(hs1, "==", hs2, " 결과", hs1 == hs2)
    fmt.Println(hs1, "==", hs3, " 결과", hs1 == hs3)

결과는 다음과 같습니다.

강감찬 == 강감찬 결과 true
강감찬 == 홍길동 결과 false
[그림 2] 비교 연산자 예제 실행 화면

 문자열 비교는 새로운 프로젝트를 만들어서 다시 한 번 살펴보기로 해요.

[그림 3] LiteIDE에서 새 프로젝트 생성 및 소스 파일 추가
// Example 문자열 비교 연산자
package main
 
import "fmt"
 
func main() {
    var s1, s2, s3 string = "abc", "zb", "ABC"
    fmt.Println("a의 아스키 코드:", 'a')
    fmt.Println("z의 아스키 코드:", 'z')
    fmt.Println("A의 아스키 코드:", 'A')
 
    fmt.Println(s1, "<", s2, " 결과", s1 < s2)
    fmt.Println(s1, "<", s3, " 결과", s1 < s3)
   
    var hs1, hs2, hs3 string = "강감찬", "킹콩", "홍길동"
    fmt.Println(hs1, "<", hs2, " 결과", hs1 < hs2)
    fmt.Println(hs1, "<", hs3, " 결과", hs1 < hs3)
}

문자열 비교는 길이 비교가 아니라 아스키 코드에 의해 사전식 비교를 한다고 했어요. 예를 들어 “abc”와 “zb”의 문자열 길이는 “abc”가 크지만 사전식 비교에서는 맨 앞 글자부터 아스키 코드를 비교합니다. “abc”의 a문자와 “zb”의 z문자의 아스키 코드(122)는 a문자의 아스키 코드(97)보다 큽니다. 그리고 “abc”와 “ABC”를 비교하면 ‘a’보다 ‘A'(65)보다 작아요.

다음은 이를 확인하는 코드예요.

  • 문자열의 비교 연산은 아스키 코드로 사전식 비교
    var s1, s2, s3 string = "abc", "zb", "ABC"
    fmt.Println("a의 아스키 코드:", 'a')
    fmt.Println("z의 아스키 코드:", 'z')
    fmt.Println("A의 아스키 코드:", 'A')
 
    fmt.Println(s1, "<", s2, " 결과", s1 < s2)
    fmt.Println(s1, "<", s3, " 결과", s1 < s3)

결과는 다음과 같아요.

a의 아스키 코드: 97
z의 아스키 코드: 122
A의 아스키 코드: 65
abc < zb 결과 true
abc < ABC 결과 false

한글도 같은 원리로 비교합니다.

  • 한글로 구성한 문자열비교
    var hs1, hs2, hs3 string = "강감찬", "킹콩", "홍길동"
    fmt.Println(hs1, "<", hs2, " 결과", hs1 < hs2)
    fmt.Println(hs1, "<", hs3, " 결과", hs1 < hs3)

결과는 다음과 같아요.

강감찬 < 킹콩 결과 true
강감찬 < 홍길동 결과 true
[그림 4] 문자열 비교 예제 실행 화면

 참고로 실수는 오차 범위를 갖고 있다는 것을 잊지 마시기 바랍니다.

[그림 5] 실수 형식의 오차로 인해 개발자의 표현한 값과 실제 값이 달라서 버그가 발생한 화면