Inhaltsverzeichnis
Frageninhalt
Workaround
Heim Backend-Entwicklung Golang Wie kann eine Codeduplizierung vermieden werden, die eine dynamische Auswahl von Typen erfordert?

Wie kann eine Codeduplizierung vermieden werden, die eine dynamische Auswahl von Typen erfordert?

Feb 10, 2024 pm 02:06 PM
overflow

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:

  1. Frame-Typ-Flag, das angibt, ob es sich um einen Video-Frame oder einen Audio-Frame handelt
  2. Titel
  3. 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)
    }
}
Nach dem Login kopieren

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)
    }
}
Nach dem Login kopieren

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) }
Nach dem Login kopieren

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]
}
Nach dem Login kopieren

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{} },
}
Nach dem Login kopieren

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.

Pakete sind ein großartiges Werkzeug, um Ihren Code trocken zu halten.) 🎜

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!

Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn

Heiße KI -Werkzeuge

Undresser.AI Undress

Undresser.AI Undress

KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover

AI Clothes Remover

Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool

Undress AI Tool

Ausziehbilder kostenlos

Clothoff.io

Clothoff.io

KI-Kleiderentferner

AI Hentai Generator

AI Hentai Generator

Erstellen Sie kostenlos Ai Hentai.

Heißer Artikel

R.E.P.O. Energiekristalle erklärten und was sie tun (gelber Kristall)
3 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Beste grafische Einstellungen
3 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. So reparieren Sie Audio, wenn Sie niemanden hören können
3 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25: Wie man alles in Myrise freischaltet
4 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌

Heiße Werkzeuge

Notepad++7.3.1

Notepad++7.3.1

Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version

SublimeText3 chinesische Version

Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1

Senden Sie Studio 13.0.1

Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6

Dreamweaver CS6

Visuelle Webentwicklungstools

SublimeText3 Mac-Version

SublimeText3 Mac-Version

Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Der Preis von Bitcoin seit seiner Geburt 2009–2025. Die umfassendste Zusammenfassung der historischen BTC-Preise Der Preis von Bitcoin seit seiner Geburt 2009–2025. Die umfassendste Zusammenfassung der historischen BTC-Preise Jan 15, 2025 pm 08:11 PM

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.

Überblick über den historischen Preis von Bitcoin seit seiner Geburt. Vollständige Sammlung historischer Preistrends von Bitcoin. Überblick über den historischen Preis von Bitcoin seit seiner Geburt. Vollständige Sammlung historischer Preistrends von Bitcoin. Jan 15, 2025 pm 08:14 PM

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.

Eine Liste der historischen Preise seit der Geburt von Bitcoin BTC Historical Price Trend Chart (neueste Zusammenfassung) Eine Liste der historischen Preise seit der Geburt von Bitcoin BTC Historical Price Trend Chart (neueste Zusammenfassung) Feb 11, 2025 pm 11:36 PM

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.

Der jüngste Preis für Bitcoin in den Jahren 2018-2024 USD Der jüngste Preis für Bitcoin in den Jahren 2018-2024 USD Feb 15, 2025 pm 07:12 PM

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:

Wie kann man das Größensymbol durch CSS anpassen und es mit der Hintergrundfarbe einheitlich machen? Wie kann man das Größensymbol durch CSS anpassen und es mit der Hintergrundfarbe einheitlich machen? Apr 05, 2025 pm 02:30 PM

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 verwendet ich das Clip-Pfad-Attribut von CSS, um den 45-Grad-Kurveneffekt des Segmenters zu erreichen? Wie verwendet ich das Clip-Pfad-Attribut von CSS, um den 45-Grad-Kurveneffekt des Segmenters zu erreichen? Apr 04, 2025 pm 11:45 PM

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 ...

Ist die H5-Seitenproduktion eine Front-End-Entwicklung? Ist die H5-Seitenproduktion eine Front-End-Entwicklung? Apr 05, 2025 pm 11:42 PM

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.

Wie kann die technische Fragen und Antworten in der Chatgpt -Ära auf Herausforderungen reagieren? Wie kann die technische Fragen und Antworten in der Chatgpt -Ära auf Herausforderungen reagieren? Apr 01, 2025 pm 11:51 PM

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

See all articles