Al escribir funciones genéricas en Go, puede resultar beneficioso aceptar también tipos concretos. Sin embargo, esto plantea un desafío al intentar inicializar porciones de interfaces con nuevas instancias de esos tipos específicos.
Un enfoque puede parecer lógico: definir dos parámetros de tipo, uno para el tipo de elemento de corte (X) y otro para el tipo concreto (Y) para crear una instancia. Sin embargo, este enfoque falla al intentar asignar una instancia de Y a un elemento de tipo X.
func Fill[X, Y any](slice []X){
for i := range slice {
slice[i] = new(Y) // not work!
}
}
Este problema surge porque el compilador pierde la relación entre la interfaz X y su implementación Y. Tanto X como Y se tratan como tipos distintos.
Para solucionar esto, se puede emplear una operación de conversión explícita dentro de la función:
func Fill[X, Y any](slice []X) {
for i := range slice {
slice[i] = any(*new(Y)).(X)
}
}
Sin embargo, este enfoque provoca pánico si Y no implementa X, lo que ocurre en escenarios como el intento de asignar un *sync.Mutex (tipo de puntero) a sync.Locker.
Una solución más sólida y con seguridad de tipos implica utilizar una función constructora:
func Fill[X any](slice []X, f func() X) {
for i := range slice {
slice[i] = f()
}
}
Esta función acepta una función constructora que devuelve una nueva instancia del tipo especificado. Esto permite una inicialización concisa y segura de sectores con instancias de tipos concretos.
En los casos en los que se pretende crear una instancia del tipo concreto con un tipo de puntero, es importante tener en cuenta ese nuevo (Y) dará como resultado un valor nulo. Para evitar esto, se puede ajustar la función constructora para que devuelva el valor correcto del puntero, como func() X { return &sync.Mutex{} }.
Descargo de responsabilidad: Todos los recursos proporcionados provienen en parte de Internet. Si existe alguna infracción de sus derechos de autor u otros derechos e intereses, explique los motivos detallados y proporcione pruebas de los derechos de autor o derechos e intereses y luego envíelos al correo electrónico: [email protected]. Lo manejaremos por usted lo antes posible.
Copyright© 2022 湘ICP备2022001581号-3