Cet article est écrit par la rubrique tutoriel golang pour vous présenter le problème de la modification du type de chaîne dans Golang. Vous vous demandez peut-être qu'il est normal que nous modifiions les chaînes dans le développement quotidien. ? Vous ne pouvez pas apporter de modifications ? Ce qui suit sera expliqué en détail avec des exemples. J’espère que cela sera utile aux amis dans le besoin !
Lorsque vous entrez en contact avec une langue comme le Go, vous entendrez souvent cette phrase. Vous vous interrogez peut-être sur le fait que les chaînes ne peuvent pas être modifiées. Il est normal que nous modifiions les chaînes dans le développement quotidien. Pourquoi disons-nous que les chaînes dans Go ne peuvent pas être modifiées ?
Cet article va vous montrer à travers un cas pratique pourquoi les chaînes en Go ne peuvent pas être modifiées.
Avant de démontrer ce problème, donnons d'abord une démonstration approximative des connaissances de base sur les types de cordes, afin que chacun puisse mieux comprendre le problème.
String est un type de données utilisé pour représenter des caractères. Lors de l'utilisation, utilisez " " pour entourer le contenu du caractère. Par exemple, la forme suivante :
package main import "fmt" func main() { var str string = "Hello World!" }
Dans Go, les chaînes sont généralement définies de trois manières :
// 第一种(全量定义) var 变量名称 string = "字符串内容" // 类型推导 var 变量名称 = "字符串内容" // 短标记(只适用于局部变量) 变量名称 := "字符串内容"
La définition des chaînes peut en fait être en termes d'octets. Les méthodes répertoriées ici sont les plus courantes.
Les chaînes en Go sont conformes à la norme Unicode et sont codées en UTF-8. La couche inférieure de la chaîne est en fait composée d'octets (cela sera expliqué en détail plus tard). Utilisez l'exemple suivant pour imprimer et afficher le contenu d'octet spécifique :
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
Le contenu imprimé par le code ci-dessus est le code d'octet représenté par chaque caractère.
Grâce à la démonstration approximative ci-dessus, nous avons une compréhension de base des chaînes. En ce qui concerne les chaînes qui ne peuvent pas être modifiées, vous vous demandez peut-être qu'il est normal que nous réaffections des chaînes dans le développement quotidien. Pourquoi disons-nous que les chaînes dans Go ne peuvent pas être modifiées ?
En fait, je souhaite corriger cette affirmation ici. La modification de chaîne n'équivaut pas à une réaffectation. La méthode couramment utilisée en développement est en fait une notion de réaffectation.
str := "Hello World!" // 重新赋值 str = "Hello Go!" // 字符串修改 str[0] = "I"
Le dicton communément entendu selon lequel il ne peut pas être modifié fait en fait référence à la deuxième manière du code ci-dessus. Et si modifié de cette manière, une erreur sera signalée : :cannot assign to s [0] (value of type byte)
Retour au sujet, pourquoi les chaînes dans Go ne peuvent-elles pas être modifiées par indice ?
En effet, la structure de données de chaîne dans Go est une structure composée d'un pointeur et d'une longueur. La tranche pointée par le pointeur est la vraie valeur de chaîne. Le code source dans Go a une telle définition :
type stringStruct struct { str unsafe.Pointer // 指向一个byte类型的切片指针 len int // 字符串的长度 }
C'est précisément parce que la couche inférieure est une tranche de type [] octet. Lorsque nous utilisons des indices pour modifier la valeur, nous attribuons ensuite un contenu de caractère au type d'octet. doit être Non autorisé. Mais nous pouvons accéder à la valeur d'octet correspondante via l'abonnement.
fmt.Println(s[0]) // output:72
Alors que devons-nous faire si nous voulons modifier la valeur via l'abonnement ? À ce stade, vous devez le définir par découpage, puis le convertir en chaîne.
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!
Ce qui précède analyse pourquoi les chaînes ne peuvent pas être attribuées à l'aide d'indices. Revenons en arrière et expliquons les méthodes d'affectation dans le développement quotidien.
package main import ( "fmt" ) func main() { // 声明一个字符串,并给与初始值 s := "Hello World!" // 对变量 s 进行重新赋值 s := "Hello Go!" }
Alors pourquoi les valeurs de chaîne peuvent-elles être réaffectées dans ce scénario ?
En effet, au bas de Go, une tranche de type [] byte {} est en fait nouvellement créée, pointant le pointeur dans la variable s vers la nouvelle adresse de l'espace mémoire (c'est-à-dire Hello Go ! ici). L'espace mémoire d'origine de Hello World ! sera récupéré avec le mécanisme de récupération de place.
Peut-être que tout le monde se demandera pourquoi une chaîne ordinaire est si compliquée à concevoir et doit utiliser des pointeurs. Je n'ai trouvé aucune documentation officielle pour le moment.
Je suppose personnellement que lorsqu'on rencontre un caractère très long, cela rend la chaîne très légère et peut être facilement transférée sans se soucier de la copie de la mémoire. Bien que dans Go, qu'il s'agisse d'un passage de paramètre de type référence ou de type valeur, il est passé par valeur. Mais les pointeurs sont évidemment plus efficaces en mémoire que le passage par valeur.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!