[Golang] String(문자열)

2021-10-28 hit count image

Golang에서 String(문자열)을 선언하고 사용하는 방법에 대해서 알아봅시다.

개요

이번 블로그 포스트에서는 Golang에서 String(문자열)을 사용하여 변수를 생성하고 사용하는 방법에 대해서 살펴보려고 합니다. 이 블로그 포스트에서 소개하는 코드는 다음 링크를 통해 확인하실 수 있습니다.

문자열

Golang에서는 다음과 같이 문자열을 선언하고 사용할 수 있습니다.

str1 := "Hello\nWorld!"
fmt.Println(str1)

또한, 다음과 같이 \`을 사용하여 여러 줄의 문자열을 선언하고 사용할 수 있습니다.

str2 := `Hello
World!`
fmt.Println(str2)

이를 확인하기 위해 main.go 파일을 생성하고 다음과 같이 수정합니다.

package main

import "fmt"

func main() {
  str1 := "Hello\nWorld!"
  fmt.Println(str1)

  str2 := `Hello
World!`
  fmt.Println(str2)
}

이를 실행하면 다음과 같은 결과가 출력됩니다.

# go run main.go
Hello
World!
Hello
World!

문자열 순회

Golang에서는 다음과 같이 문자열을 순회할 수 있습니다.

str1 := "Hello, world!"

for i := 0; i < len(str1); i++ {
  fmt.Printf("%c", str1[i])
}

하지만 len()는 바이트 길이를 반환합니다. 따라서 한국어와 같이 1바이트가 아닌 문자를 사용하면 글자가 제대로 표시되지 않습니다. (한국어 > 3바이트)

str2 := "Hello, 월드!"

for i := 0; i < len(str2); i++ {
  fmt.Printf("%c", str2[i])
}

이때는 rune(int32 별칭타입) 타입을 사용하여, 문자 하나를 4바이트로 변환시킨 후, 출력해야 합니다.

str3 := "Hello, 월드!"
arr := []rune(str3)

for i := 0; i < len(arr); i++ {
  fmt.Printf("%c", arr[i])
}

이를 확인하기 위해 main.go 파일을 다음과 같이 수정합니다.

package main

import "fmt"

func main() {
  str1 := "Hello, world!"

  for i := 0; i < len(str1); i++ {
    fmt.Printf("%c", str1[i])
  }

  fmt.Println()

  str2 := "Hello, 월드!"

  for i := 0; i < len(str2); i++ {
    fmt.Printf("%c", str2[i])
  }

  fmt.Println()

  str3 := "Hello, 월드!"
  arr := []rune(str3)

  for i := 0; i < len(arr); i++ {
    fmt.Printf("%c", arr[i])
  }
}

이를 실행하면 다음과 같은 결과를 얻을 수 있습니다.

# go run main.go
Hello, world!
Hello, ìë!
Hello, 월드!%

문자열 연산

Golang에서는 문자열을 사용하여 다음과 같은 연산을 사용할 수 있습니다.

문자열 합산

Golang에서 + 연산자를 사용하여 다음과 같이 문자열을 합칠 수 있습니다.

package main

import "fmt"

func main() {
  str1 := "Hello"
  str2 := "world!"
  fmt.Println(str1 + " " + str2)

  str := "Hello"
  str += " " + "world!"
  fmt.Println(str)
}

이를 확인하기 위해 main.go 파일을 수정하고 실행하면, 다음과 같은 결과를 확인할 수 있습니다.

# go run main.go
Hello world!
Hello world!

비교 연산

Golang에서는 다음과 같이 비교 연산자를 사용하여 문자열을 비교할 수 있습니다.

package main

import "fmt"

func main() {
  str3 := "a"
  str4 := "b"
  fmt.Println(str3 == str4)
  fmt.Println(str3 != str4)
  fmt.Println(str3 < str4)
  fmt.Println(str3 > str4)
}

문자의 크기를 비교할 때에는 해당 문자의 코드 값을 사용하여 비교하게 됩니다.

  • A-Z: 65-90
  • a-z: 97-122

이를 확인하기 위해, main.go 파일을 수정하고 실행하면, 다음과 같은 결과를 얻을 수 있습니다.

# go run main.go
false
true
true
false

문자열은 포인터

Golang에서는 기본적으로 같은 크기의 데이터만 변수에 할당이 가능합니다. 하지만, 문자열은 데이터에 따라 문자열의 길이가 달라지므로, 데이터의 사이즈가 다릅니다. 하지만, 문자열은 Golang의 기본 규칙을 어기고 데이터가 할당되고 있습니다. 그 이유는 문자열이 포인터이기 때문입니다.

이를 확인하기 위해, main.go 파일을 다음과 같이 수정합니다.

package main

import (
  "fmt"
  "reflect"
  "unsafe"
)

func main() {
  str1 := "Hello, World!"
  str2 := str1

  strHeader1 := (*reflect.StringHeader)(unsafe.Pointer(&str1))
  strHeader2 := (*reflect.StringHeader)(unsafe.Pointer(&str2))

  fmt.Println(strHeader1)
  fmt.Println(strHeader2)
}

이를 실행하면 다음과 같은 결과를 얻을 수 있습니다.

&{17444156 13}
&{17444156 13}

결과를 확인해 보면, 같은 메모리 주소를 가지고 있으며, 같은 크기의 데이터가 저장된 것을 확인할 수 있습니다.

문자열은 불변이다

문자열은 기본적으로 불변(Immutable)값입니다.

package main

import "fmt"

func main() {
  str := "Hello, World!"
  str = "Hello"
  fmt.Println(str)

  // str[0] = "a" // ERROR
}

따라서 전체 재할당은 가능하지만, 하나의 문자만을 변경하는 것은 불가능합니다.

만약, 하나의 문자만을 변경하고 싶다면, 다음과 같이 문자열을 새로운 slice 변수에 할당하여 수정하면 됩니다.

package main

import "fmt"

func main() {
  var str1 string = "Hello, World!"
  var slice []byte = []byte(str1)

  slice[0] = "h"[0]
  fmt.Println(str1)
  fmt.Printf("%s\n", slice)
}

이를 실행하면 다음과 같은 결과를 얻을 수 있습니다.

# go run main.go
Hello, World!
hello, World!

strings 패키지

Golang에서 문자열을 다룰 때는 Golang에서 제공하는 strings 패키지를 사용하게 됩니다.

strings 패키지는 다양한 기능들이 매우 효율적으로 구현되어있기 때문에, 직접 구현하는 것보다 성능이 좋습니다. 그러므로, 문자열을 다루는 프로그램을 작성한다면, 위에 링크를 통해 strings 패키지가 제공하는 기능을 먼저 확인해 보는 것이 좋습니다.

package main

import (
  "fmt"
  "strings"
)

func main() {
  str := "hello, world!"
  fmt.Println(strings.ToUpper(str))
  fmt.Println(strings.Contains(str, "hello"))
  fmt.Println(strings.Index(str, "w"))
  fmt.Println(strings.Compare("a", "b"))
}

위에 내용을 실행하면 다음과 같은 결과를 얻을 수 있습니다.

# go run main.go
HELLO, WORLD!
true
7
-1

완료

이것으로 Golang에서 문자열을 생성하고 사용하는 방법에 대해서 알아보았습니다. 또한, Golang에서 문자열의 특징을 알아보았으며, Golang이 기본적으로 제공하는 strings 패키지를 사용하여, 문자열을 다루는 방법에 대해서도 알아보았습니다.

제 블로그가 도움이 되셨나요? 하단의 댓글을 달아주시면 저에게 큰 힘이 됩니다!

책 홍보

스무디 한 잔 마시며 끝내는 React Native 책을 출판한지 벌써 2년이 다되었네요.
이번에도 좋은 기회가 있어서 스무디 한 잔 마시며 끝내는 리액트 + TDD 책을 출판하게 되었습니다.

아래 링크를 통해 제가 쓴 책을 구매하실 수 있습니다.
많은 분들에게 도움이 되면 좋겠네요.

스무디 한 잔 마시며 끝내는 React Native, 비제이퍼블릭
스무디 한 잔 마시며 끝내는 리액트 + TDD, 비제이퍼블릭
Posts