Почему небезопасно. Размер считается небезопасным? - PullRequest
0 голосов
/ 24 сентября 2018

Рассмотрим следующее:

import (
    "log"
    "unsafe"
)

type Foo struct {
    Bar int32
}

func main() {
    log.Println(int(unsafe.Sizeof(Foo{})))
}

Почему определение размера переменной считается небезопасным и частью небезопасного пакета?Я не понимаю, почему получение размера любого типа является небезопасной операцией, или какой механизм go использует для определения его размера, который требует этого.

Мне также хотелось бы знать, есть ли альтернативы небезопасному пакету для определения размера известной структуры.

Ответы [ 2 ]

0 голосов
/ 24 сентября 2018

Поскольку в Go, если вам нужно вызвать sizeof, это, как правило, означает, что вы манипулируете памятью напрямую, и вам никогда не нужно это делать.

Если вы приехали из мира Си, вы, вероятно,чаще всего использовали sizeof вместе с malloc для создания массива переменной длины - но это не нужно в Go, где вы можете просто make([]Foo, 10).В Go объем памяти, который должен быть выделен, определяется средой выполнения.

Вам не следует бояться звонить unsafe.Sizeof там, где это действительно имеет смысл - но вы должны спросить себя, действительно ли вам это нужно.

Даже если вы используете его, например, для записи двоичного формата, обычно неплохо рассчитать самостоятельно необходимое вам количество байтов или, если что-то сгенерировать, динамически, используя reflect:

  • вызов unsafe.Sizeof для структуры будет также включать число байтов, добавленных для заполнения .
  • , вызывающих его для структур динамического размера (т.е.кусочки, строки) даст длину их заголовков - вместо этого вы должны вызвать len().

Используя unsafe на uintptr, int или uint, чтобы определить,Вы работаете на 32-битной или 64-битной?Как правило, вы можете избежать этого, указав int64, где вам на самом деле нужно поддерживать числа больше 2 ^ 31.Или, если вам действительно нужно это обнаружить, у вас есть много других опций, таких как теги сборки или что-то вроде этого:

package main

import (
    "fmt"
)

const is32bit = ^uint(0) == (1 << 32) - 1

func main() {
    fmt.Println(is32bit)
}
0 голосов
/ 24 сентября 2018

Судя по небезопасному пакету, методы не используют безопасность типа go для своих операций.

https://godoc.org/unsafe

Пакет unsafe содержит операции, обходящие типбезопасность программ Go.

Пакеты, которые импортируют небезопасно, могут быть непереносимыми и не защищены рекомендациями по совместимости с Go 1.

Таким образом, из-за звуков небезопасностив том виде кода, который предоставляется, не обязательно из его вызова, в частности

...