golang - string

아래 글은 golang을 공부할 목적으로 웹에서 본 글들을 정리한 것이다.

[]byte를 string으로 변환 시 널 문자 제거하기

var rawUserID []byte

userID := strings.Trim(string(rawUserID), "\x00")

byte array to string

출처

s := string(byteArray[:])
s := string(byteArray[:n])
str := fmt.Sprintf("%s", byteArray)

[]string 타입 슬라이스를 하나의 문자열로

단순히 문자열들을 연결하는 것은 +연산자로 되므로, 이번에는 문자열을 저장한 슬라이스들을 하나의 문자열로 만든다.

package main

import (
        "fmt"
        "strings"
)

func main() {
        s := []string{"안녕", "세상"}
        fmt.Println(strings.Join(s, ""))
}

이렇게 하면 ‘안녕세상’ 이라고 출력.

string을 []byte로 캐스트 할 때 메모리 복사를 하지 않는 방법

  • []byte(str)
  • 위 방법으로 캐스팅하면 메모리 복사가 발생한다.
  • 좀 위험한(?) 방법이지만 unsafe를 사용하면 메모리 복사를 하지 않을 수 있다.
package main

import (
    "fmt"
    "unsafe"
)

func main() {
    str := "hello, world!"
    vec := *(*[]byte)(unsafe.Pointer(&str))
    fmt.Println(vec)
}
  • 포인터 연산도 가능하다.
package main

import (
    "unsafe"
)

type foo struct {
    k int64
    v int64
}

func main() {
    f := &foo{3,4}

    // unsafe.Pointer() 익명 포인터로 해서
    // uintptr() 연산 가능으로 해서
    // +8 바이트(64bit) 더해서
    // unsafe.Pointer 에서 익명 포인터에 넘기고
    // 그기에서 필드 v 있으므로 *int64  캐스트 해서
    // 디리퍼런스 하면 완성
    *(*int64)(unsafe.Pointer((uintptr(unsafe.Pointer(f))+8))) = 5

    println(f.v) // 5
}

string과 rune

  • string은 사실 read-only한 byte조각. 속은 UTF-8 라고 할 수 없다.
  • Go의 소스 코드는 UTF-8로 써야 하는 rule이 있다.
  • 소스가 올바르게 UTF-8로 쓰여 있으면 리터럴로 초기화된 string은 UTF-8이 된다.
  • len(string)은 byte 수 반환
  • string[n]은 인덱스 n의 byte(int8)
const sample = "일본어"
for i := 0; i < len(sample); i++ {
        fmt.Printf("%x ", sample[i])
}
// 결과
e6 97 a5 e6 9c ac e8 aa 9e
  • rune의 Unicode 코드 포인트. int32의 alias
  • (UTF-8의)string을 range로 돌리면 rune이 된다
const nihongo = "일본어&quot;
for index, runeValue := range nihongo {
        fmt.Printf("%#U starts at byte position %d\n", runeValue, index)
}
↓ 결과
U+65E5'일'starts at byte position 0
U+672C'본'starts at byte position 3
U+8A9E'어'starts at byte position 6
  • rune을 좀 더 정교하게 다루고 싶다면 unicode/utf8 패키지 활용.

Go에서 멀티 바이트가 혼합된 문자열을 truncate 하기

  • Go에서 영어 이외의 string을 그대로 truncate하면 [] byte로 잘라져서 글자가 깨어진다.
s : = "아 aa 아"

// 5 번째 문자까지 삭감하고
fmt.Println (s [0 : 5]) // => 아??
  • [] rune ([] int32의 alias)로 변환하고 필요한만큼 잘라서 string으로 캐스팅 하면된다.
s : = "아 aa 아"
r : = [] rune (s)

// 5 번째 문자까지 짜른다
fmt.Println (string (r [0 : 5])) // => 아 aa 아

문자열 포맷

fmt.Sprintf("[DummyId: %n]", dummy.index)

참고


이 글은 2018-11-24에 작성되었습니다.