Maison  >  Article  >  développement back-end  >  Le moyen le plus efficace de créer des clés de carte uniques dans Go

Le moyen le plus efficace de créer des clés de carte uniques dans Go

WBOY
WBOYavant
2024-02-11 17:06:10539parcourir

在 Go 中创建唯一映射键的最有效方法

Dans le langage Go, le moyen le plus efficace de créer des clés de mappage uniques a toujours été une préoccupation pour les développeurs. Face à des scénarios dans lesquels les clés doivent être uniques, nous devons trouver une méthode efficace et fiable. L'éditeur PHP Baicao partagera dans cet article l'une des méthodes les plus efficaces pour vous aider à créer des clés de mappage uniques dans le langage Go, rendant votre code plus optimisé et efficace. Que vous traitiez des données à grande échelle ou que vous implémentiez des applications hautement concurrentes, ces méthodes peuvent vous aider à améliorer les performances et l'efficacité. Découvrons-le ensemble !

Contenu de la question

J'en ai une map[any]SomeType quelque part dans la bibliothèque. Je souhaite que les utilisateurs de la bibliothèque puissent créer des clés pour cette carte afin qu'elles soient garanties de ne pas entrer en conflit au sein d'une seule exécution d'application, et je souhaite que ces clés soient efficaces pour les recherches de carte.

La première chose qui me vient à l'esprit est d'utiliser l'adresse mémoire d'un objet vide unique. Mais tout ce que j'ai essayé jusqu'à présent a échoué :

<code>package main

import "fmt"

var key1 = &struct{}{}
var key2 = &struct{}{}

var key3 = struct{}{}
var key4 = struct{}{}

var key5 = new(struct{})
var key6 = new(struct{})

func main() {
    fmt.Println("key1 == key2", key1 == key2)
    fmt.Println("key3 == key4", &key3 == &key4)
    fmt.Println("key5 == key6", key5 == key6)
    test(key1, key2, "func12")
    test(&key3, &key4, "func34")
    test(key5, key6, "func56")
}

func test(a, b any, msg string) {
    fmt.Println(msg, a == b)
}
</code>

Imprimer

key1 == key2 true
key3 == key4 false
key5 == key6 true
func12 true
func34 true
func56 true

Donc, obtenir l'adresse d'une variable de structure vide est presque réalisable jusqu'à ce que vous la transmettiez à une fonction. Puis la différence disparaît.

Je ne souhaite pas introduire un registre de clés car c'est une complication inutile. Je ne veux pas non plus utiliser de chaînes, car différents consommateurs de la bibliothèque devraient négocier des clés ou utiliser des espaces de noms, et la nécessité de hacher et de comparer des chaînes est également une complication inutile.

Y a-t-il des méthodes auxquelles je n'ai pas pensé ?

Solution de contournement

La bibliothèque standard utilise la partie context.Context 时使用了一个“技巧”:上下文能够在其中携带任意值,并且这些值使用 interface{} 进行键控(从一段时间以来 any)1。然后,您自己的包可以为其将要使用的上下文键定义一个新的未导出类型,然后定义一组具有该类型的常量作为该包已知的上下文键。现在的技巧是,类型始终是 interface{} de n'importe quelle valeur de type, il n'est donc pas possible de créer des valeurs d'interface qui entrent en conflit avec les clés du package.

En gros, c'est comme ça :

package mypkg

type contextKey int

const (
  KeyFoo = contextKey(iota)
  KeyBar
)

Maintenant, lorsque vous exécutez key interface{} = KeyFoo 时,几乎可以保证程序中任何其他代码段都不能具有与 key 相同的值,因为其中一部分将(指向的内部指针)未导出输入 contextKey. Vous voudrez peut-être lire cet article classique pour comprendre son fonctionnement (un peu rouillé, mais toujours correct à 99%)).

Pour moi, cela ressemble à une voie à suivre : les utilisateurs de votre package peuvent générer leurs propres clés et les soumettre à votre carte, qui doit avoir un type de clé de interface{}any. Il n’est pas nécessaire de disposer d’un registre centralisé pour remettre ces clés.

1 Voir context.Context.Value() et context.WithValue() pour plus d'informations. Ce dernier fournit plus de conseils sur la façon de générer la clé.

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!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer