이 글은 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 // 字符串的长度 }
이는 바로 아래쪽 레이어가 [] 바이트 유형의 조각이기 때문입니다. 값을 수정하기 위해 첨자를 사용할 때 문자 내용을 바이트 유형에 할당합니다. 허용되지 않아야 합니다. 하지만 첨자를 통해 해당 바이트 값에 액세스할 수 있습니다.
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! 메모리 공간은 가비지 수집 메커니즘을 통해 회수됩니다.
아마도 일반 문자열이 설계하기가 왜 그렇게 복잡하고 포인터를 사용해야 하는지 다들 생각할 것입니다.
아주 긴 문자를 만날 때 문자열을 매우 가볍게 만들고 메모리 복사에 대한 걱정 없이 쉽게 전송할 수 있다는 것이 개인적인 추측입니다. Go에서는 참조 유형이든 값 유형 매개변수 전달이든 값으로 전달됩니다. 그러나 포인터는 값으로 전달하는 것보다 분명히 더 메모리 효율적입니다.
위 내용은 Golang 문자열 유형을 수정할 수 없는 이유는 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!