rune

(한글, 유니코드, UTF-8)

 

 

rune 타입은 다른 언어에서 잘 볼 수 없는 타입이다. 타입의 이름을 왜 rune으로 정의했을까 궁금증으로 찾아보니, 룬 문자(runic alphabets)에서 가져온건 아닐까 생각된다. 룬 문자는 옛날에 북유럽의 게르만족(=독일사람)이 라틴문자를 사용하기 전에 사용되던 문자라고 한다. 아래 첨부한 그림에 포함된 글이 룬 문자로 작성된 것이라고 한다. 바로 이 문자를 컴퓨터로 표현할 수 있는 인코딩 타입 중 하나가 유니코드이다. 룬 문자에 대한 유니코드가  U+16A0 ~ U+16FF 사이에 정의되어있기 때문에, 개발자가 원한다면 프로그램 위에 출력시킬 수도 있다. 이러한 정황들을 봤을 때, 개인적으로 잠깐 "go언어를 설계한 사람이 언어를 전공한 친구에게 컴퓨터에 모든 문자를 표현할 수 있는 타입이 하나 있는데 작명을 부탁한 후, runic alphabet을 의미하는 rune이라는 이름을 받아오진 않았을까"생각해봤다.

 

 

[ unicode - runic alphabet ]

 

rune 타입은 유니코드(UTF-8/Unicode)를 쉽게 제어하기 위한 타입이다. Go 언어의 rune 타입은 int32을 재정의해서 사용되고 있다. 따라서 32bit로 제어되고 있다는 것을 알 수 있다. 직접 코딩을 할 때는 "unicode/utf8"패키지에서 제공하는 API들을 사용해서 rune 타입관련 함수들을 쉽게 활용할 수도 있으니 참고바란다. 추가로, 아래 영어로 작성된 문장은 go lang 문서에서 rune 타입을 어떻게 정의했는지에 대해 설명하는 내용이다.

 

"rune is an alias for int32 and is equivalent to int32 in all ways. It is used, by convention, to distinguish character values from integer values."

 

 

 

rune : 유니코드(UTF-8)을 표현하는 타입

  • 16 bit로 표현되는 UTF-16이 아닌, 8 bit로 표현되는 UTF-8 (8-bit Unicode Transformation Format) 인코딩 방식을 사용한다는 것을 주의한다.

  • 유니코드 인코딩에서 한글은 3byte를 사용하고, 영어는 1byte를 사용하는 것을 주의한다.

  • 유니코드는 한글을 지원하는 인코딩 방식이기 때문에, 한글을 사용하는 프로그램 개발에 유용하게 사용할 수 있다.

 

[ unicode table - U+D600 ~ U+D77F]
[ unicode - UTF-8]

 

sample code

아래 코드는 rune 타입을 사용한 몇가지 코드들이 작성되어 있다. '홍' 글자를 UTF-8 단위로 제어할 수 있는 rune 타입을 사용한 예제이다. '홍' 글자를 unicode 표에서 찾아보면 U+D64D에 해당하는 것을 알 수 있다. 이 값을 코드로 작성하면 '\ud64d'로 표현할 수 있다. 참고로, 아래 예제 코드는 go language 기준으로 작성되었으니 다른 언어는 조금 다를 수도 있다는 것을 알아두자. 아래 코드를 실행하면 UTF-8 인코딩 기준의 '홍'값을, 10진수로 표현하면 54861이라는 값을 가지고, 한글 문자이므로 3byte가 필요하기때문에 출력도 동일하게 되는 것을 알 수 있다. 참고로, 영어 알파벳 문자인 'a' 값은 1byte가 필요하다.

package main

import (
    "fmt"
    "unicode/utf8"
)

func main() {
    // get rune from string
    var r1 rune
    str := "홍길동"
    r1 = []rune(str)[0]

    // get rune from character
    var r2 rune
    r2 = '홍'
    
    // get rune from character (unicode point)
    var r3 rune
    r3 = '\ud64d'
    
    // get len of rune type (한글) 
    len1 := utf8.RuneLen('홍')
    
    // get len of rune type (영어)
    len2 := utf8.RuneLen('a')
    
    fmt.Println(r1, r2, r3, len1, len2)
}

// 출력
// 54861 54861 54861 3 1

 

 

byte : 아스키(ASCII) 코드로 표현하는 타입

  • 8bit 인코딩 방식이라는 것을 주의한다. 첫 비트는 0으로 시작하고 나머지 7개 비트로 표현하는 방식이다.

[ ascii code table ]

 

sample code

아래 코드는 byte 타입을 사용한 예제 코드이다. byte 타입은 1바이트 크기 내에서 표현되고, 7bit로 표현되는 ASCII코드로 많이 사용되는 타입이기 때문에, 이미 알고 있을 것으로 생각되어 자세한 설명은 추가하지 않았다.

package main

import (
    "fmt"
)

func main() {
    // get byte from string
    var b1 byte
    str := "apple"
    b1 = []byte(str)[0]

    // get byte from character
    var b2 byte
    b2 = 'a'
    
    // get byte from character (ascii)
    var b3 byte
    b3 = 97

    // get byte from character (hex)
    var b4 byte
    b4 = 0x61
    
    // get len of byte type
    bLen := len("a")
    
    fmt.Println(b1, b2, b3, b4, bLen)
}

// 출력
// 97 97 97 97 1

 

 

참고

룬 문자 (runic alphabet) link

유니코드 테이블 (unicode table) link

유니코드 UTF-8 표현 (unicode - utf-8) linklink2

아스키 테이블 (ascii code) link

고 언어 문서 (go lang builtin 타입 - rune) link