


Comment éviter la duplication de code qui nécessite une sélection dynamique de types ?
Lors de l'écriture de code, nous rencontrons souvent des situations où nous devons choisir différents types de code en fonction de différentes conditions. Dans ce cas, sans une manipulation appropriée, le code peut devenir verbeux et répétitif. Alors, comment éviter cette duplication de code ? L'éditeur PHP Baicao vous a apporté des solutions simples et efficaces, jetons-y un œil !
Contenu de la question
Le code suivant est un exemple simplifié d'analyseur de flux vidéo. L'entrée est constituée de données binaires contenant des images vidéo et audio. Chaque cadre se compose des parties suivantes :
- Drapeau de type d'image, indiquant s'il s'agit d'une image vidéo ou d'une image audio
- Titre
- Charge utile
L'objectif est d'analyser le flux, d'extraire les champs des en-têtes et de la charge utile.
Donc, la première méthode est :
package main import ( "fmt" "encoding/binary" "bytes" ) type Type byte const ( Video Type = 0xFC Audio Type = 0xFA ) var HMap = map[Type]string { Video: "Video", Audio: "Audio", } type CommonHeader struct { Type Type } type HeaderVideo struct { Width uint16 Height uint16 Length uint32 } type HeaderAudio struct { SampleRate uint16 Length uint16 } func main() { data := bytes.NewReader([]byte{0xFC, 0x80, 0x07, 0x38, 0x04, 0x02, 0x00, 0x00, 0x00, 0xFF, 0xAF, 0xFA, 0x10, 0x00, 0x01, 0x00, 0xFF}) var cHeader CommonHeader var dataLength int for { err := binary.Read(data, binary.LittleEndian, &cHeader) if err != nil { break } fmt.Println(HMap[cHeader.Type]) switch cHeader.Type { case Video: var info HeaderVideo binary.Read(data, binary.LittleEndian, &info) dataLength = int(info.Length) fmt.Println(info) case Audio: var info HeaderAudio binary.Read(data, binary.LittleEndian, &info) dataLength = int(info.Length) fmt.Println(info) } payload := make([]byte, dataLength) data.Read(payload) fmt.Println(payload) } }
Cela fonctionne, mais je n'aime pas la duplication de code dans le cas switch
. Essentiellement, nous devons répéter le même code, simplement parce que le type de trame est différent.
Une façon d’essayer d’éviter la duplication est :
package main import ( "fmt" "encoding/binary" "bytes" ) type Type byte const ( Video Type = 0xFC Audio Type = 0xFA ) var HMap = map[Type]string { Video: "Video", Audio: "Audio", } type CommonHeader struct { Type Type } type Header interface { GetLength() int } type HeaderVideo struct { Width uint16 Height uint16 Length uint32 } func (h HeaderVideo) GetLength() int { return int(h.Length) } type HeaderAudio struct { SampleRate uint16 Length uint16 } func (h HeaderAudio) GetLength() int { return int(h.Length) } var TMap = map[Type]func() Header { Video: func() Header { return &HeaderVideo{} }, Audio: func() Header { return &HeaderAudio{} }, } func main() { data := bytes.NewReader([]byte{0xFC, 0x80, 0x07, 0x38, 0x04, 0x02, 0x00, 0x00, 0x00, 0xFF, 0xAF, 0xFA, 0x10, 0x00, 0x01, 0x00, 0xFF}) var cHeader CommonHeader for { err := binary.Read(data, binary.LittleEndian, &cHeader) if err != nil { break } fmt.Println(HMap[cHeader.Type]) info := TMap[cHeader.Type]() binary.Read(data, binary.LittleEndian, info) fmt.Println(info) payload := make([]byte, info.GetLength()) data.Read(payload) fmt.Println(payload) } }
C'est-à-dire que nous introduisons la méthode TMap
映射来实现动态类型选择,该映射允许根据帧类型创建正确结构的实例。但是,此解决方案的代价是对每种帧类型重复 GetLength()
.
Je trouve très troublant qu'il semble n'y avoir aucun moyen d'éviter complètement la duplication. Est-ce qu'il me manque quelque chose, ou est-ce juste une limitation de la langue ?
Il s'agit d'une question connexe (en fait déclenchée par le même problème), cependant, sa prémisse ignore la nécessité d'une sélection de type dynamique, donc la solution acceptée (utilisant des génériques) n'aide pas.
Solution de contournement
La réponse de King nécessite qu'elle soit répétée pour chaque type entier utilisé pour coder la longueur. La réponse de Mondarin utilise le package génial reflect
. Voici une solution pour éviter les deux problèmes. Cette réponse est basée sur la réponse de King.
Déclarez les types génériques à l'aide de la méthode GetLength().
type Length[T uint8 | uint16 | uint32 | uint64] struct { Length T } func (l Length[T]) GetLength() int { return int(l.Length) }
Supprimez la méthode GetLength de chaque type d'en-tête. Intégrez un type de longueur commun dans chaque type d'en-tête :
type HeaderVideo struct { Width uint16 Height uint16 Length[uint32] } type HeaderAudio struct { SampleRate uint16 Length[uint16] }
Indiqué dans la question TMap
as。 GetLength
La méthode est fournie par un champ intégré.
var TMap = map[Type]func() Header{ Video: func() Header { return &HeaderVideo{} }, Audio: func() Header { return &HeaderAudio{} }, }
https://www.php.cn/link/ceb9f6b8ffa77c49b6b4570ea19c76bf
(Comme le code dans la question, cette réponse utilise le package binary.Read
函数间接使用 reflect
包。reflect
indirectement via la fonction binary.Read
.
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!

Outils d'IA chauds

Undresser.AI Undress
Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover
Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool
Images de déshabillage gratuites

Clothoff.io
Dissolvant de vêtements AI

AI Hentai Generator
Générez AI Hentai gratuitement.

Article chaud

Outils chauds

Bloc-notes++7.3.1
Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise
Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1
Puissant environnement de développement intégré PHP

Dreamweaver CS6
Outils de développement Web visuel

SublimeText3 version Mac
Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Depuis sa création en 2009, Bitcoin est devenu un leader dans le monde des cryptomonnaies et son prix a connu d’énormes fluctuations. Pour fournir un aperçu historique complet, cet article compile les données sur les prix du Bitcoin de 2009 à 2025, couvrant les principaux événements du marché, les changements de sentiment du marché et les facteurs importants influençant les mouvements de prix.

Le Bitcoin, en tant que crypto-monnaie, a connu une volatilité importante sur le marché depuis sa création. Cet article fournira un aperçu du prix historique du Bitcoin depuis sa naissance pour aider les lecteurs à comprendre ses tendances de prix et ses moments clés. En analysant les données historiques sur les prix du Bitcoin, nous pouvons comprendre l'évaluation de sa valeur par le marché, les facteurs affectant ses fluctuations et fournir une base pour les décisions d'investissement futures.

Depuis sa création en 2009, le prix de Bitcoin a connu plusieurs fluctuations majeures, passant à 69 044,77 $ en novembre 2021 et tombant à 3191,22 $ en décembre 2018. En décembre 2024, le dernier prix a dépassé 100 204 $.

Prix USD Bitcoin en temps réel Facteurs qui affectent le prix du bitcoin Indicateurs pour prédire les prix des futurs bitcoins Voici quelques informations clés sur le prix du bitcoin en 2018-2024:

Nœud important pour le prix historique du Bitcoin 3 janvier 2009: Genesis Block a été généré, le premier Bitcoin a été généré, avec une valeur de 0 USD. 5 octobre: La première transaction Bitcoin, un programmeur a acheté deux pizzas avec 10 000 Bitcoins, ce qui équivaut à 0,008 $. 9 février 2010: Le Mt. Gox Exchange est allé en ligne et est devenu la plate-forme principale du commerce du bitcoin précoce. 22 mai: Bitcoin percède 1 $ pour la première fois. 17 juillet: le prix du bitcoin a plongé à 0,008 $, atteignant un creux historique. 9 février 2011: Le prix du bitcoin perdra 10 $ pour la première fois. 10 avril: Mt. Go

La communauté technique de questions-réponses à l'ère Chatgpt: Stratégie de réponse de SegmentFault StackOverflow ...

Comment réaliser l'effet de courbe à 45 degrés du segmenter? Dans le processus de mise en œuvre du segmentant, comment faire transformer la bordure droite en une courbe de 45 degrés lorsque vous cliquez sur le bouton gauche, et le point ...

La méthode de personnalisation des symboles de redimension dans CSS est unifiée avec des couleurs d'arrière-plan. Dans le développement quotidien, nous rencontrons souvent des situations où nous devons personnaliser les détails de l'interface utilisateur, tels que l'ajustement ...
