>  기사  >  백엔드 개발  >  Golang 문자열 유형을 수정할 수 없는 이유는 무엇입니까?

Golang 문자열 유형을 수정할 수 없는 이유는 무엇입니까?

藏色散人
藏色散人앞으로
2022-11-21 17:34:401558검색

이 글은 golang 튜토리얼에서 golang의 문자열 유형 수정 문제를 소개하기 위해 작성되었습니다. Go에서 문자열을 수정하는 것은 흔한 일입니다. ? 변경할 수 없나요? 다음은 예시와 함께 자세히 설명하겠습니다. 도움이 필요한 친구들에게 도움이 되길 바랍니다!

바둑 같은 언어를 접하다 보면 이런 문장을 자주 듣게 되실 겁니다. 문자열을 수정할 수 없다는 사실이 궁금하실 수도 있습니다. 일상적인 개발에서 문자열을 수정하는 것은 왜 Go에서 문자열을 수정할 수 없다고 말하는 걸까요?

이 글에서는 Go에서 문자열을 수정할 수 없는 실제 사례를 보여드리겠습니다.

이 문제를 시연하기 전에 먼저 모든 사람이 문제를 더 잘 이해할 수 있도록 문자열 유형에 대한 기본 지식을 대략적으로 시연해 보겠습니다.

문자열 정의

문자열은 문자를 나타내는 데 사용되는 데이터 유형입니다. 사용 시 " "를 사용하여 문자 내용을 묶습니다. 예를 들어 다음 형식은 다음과 같습니다.

package main
import "fmt"
func main() {
    var str string = "Hello World!"
}

Go에서 문자열은 일반적으로 세 가지 방식으로 정의됩니다.

// 第一种(全量定义)
var 变量名称 string = "字符串内容"
// 类型推导
var 变量名称 = "字符串内容"
// 短标记(只适用于局部变量)
变量名称 := "字符串内容"

문자열의 정의는 실제로 바이트 단위로 정의될 수 있습니다. 여기에 나열된 방법은 가장 일반적인 방법입니다.

문자열 구성

Go의 문자열은 유니코드 표준을 따르며 UTF-8로 인코딩됩니다. 문자열의 맨 아래 레이어는 실제로 바이트로 구성됩니다(자세한 내용은 나중에 설명하겠습니다). 특정 바이트 내용을 인쇄하고 보려면 다음 예를 사용하십시오.

s := "Hello World!"
for _, v := range s {
    fmt.Print(v)
    fmt.Print("\t")
}
// 72 101 108 108 111 32 87 111 114 108 100 33

위 코드로 인쇄된 내용은 각 문자가 나타내는 바이트 코드입니다.

문자열은 수정할 수 없습니다

위의 대략적인 시연을 통해 문자열에 대한 기본적인 이해가 되었습니다. 수정할 수 없는 문자열에 대해서는 일상적인 개발에서 문자열을 다시 할당하는 것이 왜 Go에서 문자열을 수정할 수 없다고 말하는지 궁금할 것입니다.

사실 여기서는 이 문장을 수정하고 싶습니다. 문자열 수정은 재할당과 동일하지 않습니다. 개발에서 일반적으로 사용되는 방법은 실제로 재할당(Relocation)이라는 개념입니다.

str := "Hello World!"
// 重新赋值
str = "Hello Go!"
// 字符串修改
str[0] = "I"

수정이 불가능하다는 말은 사실 위 코드의 두 번째 방법을 의미합니다. 그리고 이런 식으로 수정하면 오류가 보고됩니다: :cannot 할당 to s [0] (바이트 유형의 값)

주제로 돌아가서, Go의 문자열을 첨자로 수정할 수 없는 이유는 무엇입니까?

Go의 문자열 데이터 구조는 포인터와 길이로 구성된 구조이기 때문입니다. 포인터가 가리키는 슬라이스가 실제 문자열 값입니다. Go의 소스 코드에는 다음과 같은 정의가 있습니다.

type stringStruct struct {
    str unsafe.Pointer // 指向一个byte类型的切片指针
    len int // 字符串的长度
}

Golang 문자열 유형을 수정할 수 없는 이유는 무엇입니까?

이는 바로 아래쪽 레이어가 [] 바이트 유형의 조각이기 때문입니다. 값을 수정하기 위해 첨자를 사용할 때 문자 내용을 바이트 유형에 할당합니다. 허용되지 않아야 합니다. 하지만 첨자를 통해 해당 바이트 값에 액세스할 수 있습니다.

fmt.Println(s[0]) // output:72

그럼 첨자를 통해 값을 수정하려면 어떻게 해야 할까요? 이때 슬라이싱을 통해 정의한 후 문자열로 변환해 주어야 합니다.

package main
import (  
    "fmt"
)
func main() {  
     s1 := []byte{72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 33}
    fmt.Println(string(s1))
    // 将"H"修改为l
    s1[0] = 108
    fmt.Println(string(s1))
}
// output:
Hello World!
lello World!

문자열 할당

위에서는 첨자를 사용하여 문자열을 할당할 수 없는 이유를 분석했습니다. 다시 돌아가 일상 개발에서 할당 방법을 설명하겠습니다.

package main
import (  
    "fmt"
)
func main() {
    // 声明一个字符串,并给与初始值
    s := "Hello World!"
    // 对变量 s 进行重新赋值
    s := "Hello Go!"
}

그렇다면 이 시나리오에서 왜 문자열 값을 재할당할 수 있나요?

이것은 Go의 하단에 [] byte {} 유형의 슬라이스가 실제로 새로 생성되어 변수 s의 포인터가 새 메모리 공간 주소(즉, 여기서는 Hello Go!)를 가리키기 때문입니다. 원래 Hello World! 메모리 공간은 가비지 수집 메커니즘을 통해 회수됩니다.

Golang 문자열 유형을 수정할 수 없는 이유는 무엇입니까?

왜 이렇게 설계되었나요

아마도 일반 문자열이 설계하기가 왜 그렇게 복잡하고 포인터를 사용해야 하는지 다들 생각할 것입니다.

아주 긴 문자를 만날 때 문자열을 매우 가볍게 만들고 메모리 복사에 대한 걱정 없이 쉽게 전송할 수 있다는 것이 개인적인 추측입니다. Go에서는 참조 유형이든 값 유형 매개변수 전달이든 값으로 전달됩니다. 그러나 포인터는 값으로 전달하는 것보다 분명히 더 메모리 효율적입니다.

위 내용은 Golang 문자열 유형을 수정할 수 없는 이유는 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 learnku.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제