Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

188
Vistas
Switch on interface type without type assertion

I have a function that can take a number of different argument types. I'd like to use a type switch and reduce code duplication as much as possible. As a very basic example, here I want to copy both uint8 and int8 types into a byte buffer. This code happily works

package main

func switchFn(args ...interface{}) {
    var buf []byte
    for _, arg := range args {
        switch val := arg.(type) {
        case uint8:
            buf = append(buf, byte(val))
        case int8:
            buf = append(buf, byte(val))
        }
    }
}

func main() {
    switchFn(int8(42), uint8(42)) // etc
}

You'll notice both the case statements do exactly the same thing! If I combine them though...

package main

func switchFn(args ...interface{}) {
    var buf []byte
    for _, arg := range args {
        switch val := arg.(type) {
        case uint8, int8:
            buf = append(buf, byte(val))
        }
    }
}

func main() {
    switchFn(int8(42), uint8(42)) // etc
}

I run into an issue of cannot convert val (type interface {}) to type byte: need type assertion. But I'm literally switching on the type! Argh!

Am I stuck with the code duplication here, or is there a smarter way to do this? Note that the copying into byte buffer is used to illustrate the example, my function may be doing other things in the case blocks.

over 4 years ago · Santiago Trujillo
2 Respuestas
Responde la pregunta

0

Here's a way to avoid the code duplication, at the cost of ... well, a different sort of code duplication:

func switchFn(args ...interface{}) {
    var buf []byte
    for _, arg := range args {
        var val byte
        switch v := arg.(type) {
        case uint8:
            val = byte(v)
        case int8:
            val = byte(v)
        default:
            panic("wrong type")
        }
        buf = append(buf, val)
    }
}

For this particular function, the original duplication is probably better. Should the buf = append(buf, val) section get larger or more complicated, this would probably be better.

In still other cases—perhaps most real ones—the method gopher suggests is probably best:

    f := func(val byte) {
        buffer = append(buffer, val)
    }

You can now call f from each case.

over 4 years ago · Santiago Trujillo Denunciar

0

The cases can be combined, but val will have type interface{} in the block. That's not useful for your scenario.

Use a function to reduce code duplication.

func switchFn(args ...interface{}) {
    var buf []byte

    byteFn := func(b byte) {
        buf = append(buf, b)
    }

    for _, arg := range args {
        switch val := arg.(type) {
        case uint8:
            byteFn(val)
        case int8:
            byteFn(byte(val))
        }
    }
}

The reflect API will not help because separate code is required for the signed and unsigned values. The reflect API is helpful for combining all signed integers into block of code and all unsigned integers into another block of code.

for _, arg := range args {
    switch val := arg.(type) {
    case int, int8, int16, int32, int64:
        i := reflect.ValueOf(val).Int()
        // i is an int64
        fmt.Println(i)
    case uint, uint8, uint16, uint32, uint64:
        u := reflect.ValueOf(val).Uint()
        // u is an uint64
        fmt.Println(u)
    }
}
over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda