es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Comportamiento diferente de len() con valor constante o no constante.

El código a continuación:

const s = "golang.go"

var a byte = 1 << len(s) / 128

El resultado de a es 4. Sin embargo, después de cambiar const s a var s como se muestra a continuación:

var s = "golang.go"

var a byte = 1 << len(s) / 128

Ahora el resultado de a es 0.

También hay otros códigos de prueba como el siguiente:

const s = "golang.go"

var a byte = 1 << len(s) / 128 // el resultado de a es 4
var b byte = 1 << len(s[:]) / 128 // el resultado de b es 0

var ss = "golang.go"

var aa byte = 1 << len(ss) / 128 // el resultado de aa es 0
var bb byte = 1 << len(ss[:]) / 128 // el resultado de bb es 0

Es extraño que b sea 0 al evaluar la longitud de s[:].

Intento entenderlo según la especificación de Golang:

La expresión len(s) es constante si s es una constante de cadena. Las expresiones len(s) y cap(s) son constantes si el tipo de s es un array o un puntero a un array y la expresión s no contiene recepciones de canal ni llamadas a funciones (no constantes).

Pero no lo consigo. ¿Podría alguien explicármelo de manera más clara?

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Parece que el problema tiene que ver con el uso de cadenas constantes frente a variables en combinación con el operador de desplazamiento de bits.

    En el primer ejemplo, const s = "golang.go" es una cadena constante, por lo que la expresión len(s) también es una constante. Por lo tanto, al realizar 1 << len(s) / 128, se realiza primero la operación de división, lo que resulta en len(s) / 128 = 1, luego se realiza la operación de desplazamiento de bits, lo que resulta en 1 << 1 = 2, que luego se convierte al tipo byte y se asigna a a. Sin embargo, es importante tener en cuenta que la operación de desplazamiento de bits se evalúa antes de la división, por lo que si desea dividir el resultado de un desplazamiento de bits, debe usar paréntesis para garantizar que la operación se realice en el orden correcto.

    En el segundo ejemplo, var s = "golang.go" es una cadena variable, por lo que la expresión len(s) no es constante. Como resultado, al realizar 1 << len(s) / 128, se realiza primero la operación de división, lo que resulta en len(s) / 128 = 0, luego se realiza la operación de desplazamiento de bits, lo que resulta en 1 << 0 = 1, que luego se convierte al tipo byte y se asigna a a.

    En cuanto al comportamiento extraño de que b sea 0 con s[:], es más probable que se deba al hecho de que s[:] crea una nueva sección con el mismo arreglo subyacente que s, pero con una longitud y capacidad igual a la longitud de s. Cuando se evalúa len (s [:]), devuelve el mismo valor que len (s). Sin embargo, dado que s [:] no es una expresión constante, la expresión len (s [:]) / 128 se evalúa como cero, lo que resulta en 1 << 0 = 1, que luego se convierte al tipo byte y se asigna a b.

    Se observa el mismo comportamiento al usar una cadena variable ss, donde len (ss [:]) también se evalúa como cero, lo que resulta en 1 << 0 = 1, que luego se convierte al tipo byte y se asigna a aa y bb.

    En resumen, es importante ser consciente de la diferencia entre cadenas constantes y variables al usar el operador de desplazamiento de bits u otras operaciones que dependen de la longitud de una cadena. Además, al trabajar con secciones, es importante asegurarse de que la expresión que se está evaluando sea realmente constante, de lo contrario, puede ocurrir un comportamiento inesperado.

Comments are closed.