tutorial smart remix programador online español curso interface go language-design duck-typing memory-layout

interface - smart - ¿Qué pasa con el diseño de la memoria significa que[] T no puede convertirse a la interfaz[] en Go?



smart contracts ethereum (2)

Así que he estado leyendo estos dos artículos y esta respuesta

No se puede convertir la cadena [] a [] interfaz {} dice que el diseño de la memoria debe cambiarse.

http://jordanorelli.com/post/32665860244/how-to-use-interfaces-in-go dice que comprender la memoria subyacente hace que responder a esta pregunta sea fácil, y

http://research.swtch.com/interfaces , explica lo que está sucediendo bajo el capó.

Pero, por mi vida, no puedo pensar en una razón, en términos de la implementación de interfaces, sobre por qué [] T no se puede convertir a la interfaz [].

¿Entonces por qué?


El artículo " InterfaceSlice " trata de detallar:

Una variable con tipo []interface{} no es una interfaz. Es un segmento cuyo tipo de elemento pasa a ser la interface{} . Pero incluso dado esto, uno podría decir que el significado es claro.

Bueno, ¿verdad? Una variable con tipo []interface{} tiene un diseño de memoria específico, conocido en tiempo de compilación.

Cada interface{} ocupa dos palabras (una palabra para el tipo de contenido, la otra para los datos contenidos o un puntero a ella). Como consecuencia, un segmento con longitud N y con tipo []interface{} está respaldado por un fragmento de datos que tiene N * 2 palabras de longitud.

Ver también " ¿cuál es el significado de la interface{} en golang? "

Esto es diferente al fragmento de datos que respalda un segmento con el tipo []MyType y la misma longitud. Su porción de datos será N*sizeof(MyType) longitud.

El resultado es que no se puede asignar rápidamente algo del tipo []MyType a algo de tipo []interface{} ; los datos detrás de ellos simplemente se ven diferentes.

" por qué []string no se puede convertir a []interface{} en Ir " agrega una buena ilustración:

// imagine this is possible var sliceOfInterface = []interface{}(sliceOfStrings) // since it''s array of interface{} now - we can do anything // let''s put integer into the first position sliceOfInterface[0] = 1 // sliceOfStrings still points to the same array, and now "one" is replaced by 1 fmt.Println(strings.ToUpper(sliceOfStrings[0])) // BANG!


Lea el artículo del blog Las leyes de la reflexión , sección La representación de una interfaz .

Una variable de tipo de interfaz almacena un par: el valor concreto asignado a la variable y el descriptor de tipo de ese valor. Para ser más precisos, el valor es el elemento de datos concretos subyacente que implementa la interfaz y el tipo describe el tipo completo de ese elemento.

Entonces, si tiene un valor de []T (una porción de T ) donde T no es una interfaz, los elementos de dicha porción solo almacenan valores de tipo T , pero no almacena la información de tipo, pertenece a la porción tipo.

Si tiene un valor de tipo []inteface{} , los elementos de dicho sector contienen los valores concretos y los descriptores de tipo de esos valores.

Por lo tanto, los elementos en una []interface{} requieren más información (más memoria) que en una interfaz no []T Y si la memoria ocupada de esas 2 rebanadas no es la misma, no pueden ser simplemente "miradas" de manera diferente (miradas como un tipo de differnet). Producir uno del otro requiere trabajo adicional.