


Wie kann eine Codeduplizierung vermieden werden, die eine dynamische Auswahl von Typen erfordert?
Beim Schreiben von Code stoßen wir häufig auf Situationen, in denen wir basierend auf unterschiedlichen Bedingungen unterschiedliche Codetypen auswählen müssen. In diesem Fall kann der Code ohne ordnungsgemäße Handhabung ausführlich und sich wiederholend werden. Wie kann man also diese Codeduplizierung vermeiden? Der PHP-Editor Baicao hat Ihnen einige einfache und effektive Lösungen präsentiert, schauen wir uns das an!
Frageninhalt
Der folgende Code ist ein vereinfachtes Beispiel eines Videostream-Parsers. Bei der Eingabe handelt es sich um Binärdaten, die Video- und Audioframes enthalten. Jeder Rahmen besteht aus folgenden Teilen:
- Frame-Typ-Flag, das angibt, ob es sich um einen Video-Frame oder einen Audio-Frame handelt
- Titel
- Nutzlast
Das Ziel besteht darin, den Stream zu analysieren, Felder aus Headern und Nutzdaten zu extrahieren.
Die erste Methode ist also:
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) } }
Es funktioniert, aber mir gefällt die Codeduplizierung im switch
-Fall nicht. Im Wesentlichen müssen wir denselben Code wiederholen, nur weil der Rahmentyp unterschiedlich ist.
Eine Möglichkeit, Doppelarbeit zu vermeiden, ist:
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) } }
Das heißt, wir führen die TMap
映射来实现动态类型选择,该映射允许根据帧类型创建正确结构的实例。但是,此解决方案的代价是对每种帧类型重复 GetLength()
-Methode ein.
Ich finde es sehr beunruhigend, dass es anscheinend keine Möglichkeit gibt, Doppelarbeit vollständig zu vermeiden. Übersehe ich etwas oder ist es nur eine Einschränkung der Sprache?
Dies ist eine verwandte Frage (die tatsächlich durch dasselbe Problem ausgelöst wird), ihre Prämisse ignoriert jedoch die Notwendigkeit einer dynamischen Typauswahl, sodass die akzeptierte Lösung (Verwendung von Generika) nicht hilft.
Workaround
Kings Antwort erfordert, dass sie für jeden Ganzzahltyp wiederholt wird, der zum Codieren der Länge verwendet wird. Mondarins Antwort verwendet das tolle reflect
-Paket. Hier ist eine Lösung, um beide Probleme zu vermeiden. Diese Antwort basiert auf Kings Antwort.
Deklarieren Sie generische Typen mit der Methode GetLength().
type Length[T uint8 | uint16 | uint32 | uint64] struct { Length T } func (l Length[T]) GetLength() int { return int(l.Length) }
Entfernen Sie die GetLength-Methode aus jedem Header-Typ. Betten Sie in jeden Header-Typ einen gemeinsamen Längentyp ein:
type HeaderVideo struct { Width uint16 Height uint16 Length[uint32] } type HeaderAudio struct { SampleRate uint16 Length[uint16] }
In der Frage wurde angegeben, dass die TMap
as。 GetLength
-Methode durch ein eingebettetes Feld bereitgestellt wird.
var TMap = map[Type]func() Header{ Video: func() Header { return &HeaderVideo{} }, Audio: func() Header { return &HeaderAudio{} }, }
https://www.php.cn/link/ceb9f6b8ffa77c49b6b4570ea19c76bf
(Wie der Code in der Frage verwendet diese Antwort das binary.Read
函数间接使用 reflect
包。reflect
-Paket indirekt über die Funktion binary.Read
.
Das obige ist der detaillierte Inhalt vonWie kann eine Codeduplizierung vermieden werden, die eine dynamische Auswahl von Typen erfordert?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Heiße KI -Werkzeuge

Undresser.AI Undress
KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover
Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool
Ausziehbilder kostenlos

Clothoff.io
KI-Kleiderentferner

AI Hentai Generator
Erstellen Sie kostenlos Ai Hentai.

Heißer Artikel

Heiße Werkzeuge

Notepad++7.3.1
Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version
Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1
Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6
Visuelle Webentwicklungstools

SublimeText3 Mac-Version
Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Heiße Themen



Seit seiner Einführung im Jahr 2009 hat sich Bitcoin zu einem führenden Unternehmen in der Welt der Kryptowährungen entwickelt und sein Preis hat enorme Schwankungen erfahren. Um einen umfassenden historischen Überblick zu bieten, stellt dieser Artikel Bitcoin-Preisdaten von 2009 bis 2025 zusammen und deckt wichtige Marktereignisse, Änderungen der Marktstimmung und wichtige Faktoren ab, die die Preisbewegungen beeinflussen.

Bitcoin hat als Kryptowährung seit seiner Einführung erhebliche Marktvolatilität erlebt. Dieser Artikel bietet einen Überblick über den historischen Preis von Bitcoin seit seiner Geburt, um den Lesern zu helfen, seine Preistrends und Schlüsselmomente zu verstehen. Durch die Analyse der historischen Preisdaten von Bitcoin können wir die Einschätzung des Marktes über seinen Wert und die Faktoren, die seine Schwankungen beeinflussen, verstehen und eine Grundlage für zukünftige Investitionsentscheidungen schaffen.

Seit seiner Gründung im Jahr 2009 hat der Preis von Bitcoin im November 2021 auf 69.044,77 USD auf 69.044,77 USD gestiegen und im Dezember 2018 auf 3.191,22 USD gesunken. Ab Dezember 2024 hat der jüngste Preis 100.204 USD überschritten.

Echtzeit-Bitcoin-USD-Preis Faktoren, die den Bitcoin -Preis beeinflussen Indikatoren für die Vorhersage zukünftiger Bitcoin -Preise Hier finden Sie einige wichtige Informationen zum Preis von Bitcoin in den Jahren 2018-2024:

Die Methode zur Anpassung der Größe der Größe der Größe der Größe in CSS ist mit Hintergrundfarben einheitlich. In der täglichen Entwicklung begegnen wir häufig Situationen, in denen wir die Details der Benutzeroberfläche wie Anpassung anpassen müssen ...

Wie kann man den 45-Grad-Kurveneffekt des Segmenters erreichen? Bei der Implementierung des Segmenters verwandeln Sie den rechten Rand in eine 45-Grad-Kurve, wenn Sie auf die linke Schaltfläche klicken, und der Punkt ...

Ja, die H5-Seitenproduktion ist eine wichtige Implementierungsmethode für die Front-End-Entwicklung, die Kerntechnologien wie HTML, CSS und JavaScript umfasst. Entwickler bauen dynamische und leistungsstarke H5 -Seiten auf, indem sie diese Technologien geschickt kombinieren, z. B. die Verwendung der & lt; canvas & gt; Tag, um Grafiken zu zeichnen oder JavaScript zu verwenden, um das Interaktionsverhalten zu steuern.

Die technische Q & A -Community in der Chatgpt -Ära: SegmentFaults Antwortstrategie Stackoverflow ...
