2012-06-04 3 views
4

В качестве примера, чтобы прояснить мой вопрос, в Google Go 1.0, следующий интерфейс определяется в "io" package:Число прочитанных байтов и без знака

type Reader interface { 
    Read(p []byte) (n int, err error) 
} 

Особенно список параметров результата (n int, err error) интригует меня. Искробезопасный количество байт не может быть отрицательным, в соответствии с документацией интерфейса:

возвращает количество считанных байт (0 < = п < = LEN (р)) [...]

В C причина использования int была внутриполосным значением -1, чтобы сигнализировать об ошибке (см. Effective Go: Multiple return values). Из-за множества возвращаемых значений специальные внутриполосные значения не нужны.

Существует type uint в Go 1.0.

Какова конкретная причина использования int по сравнению с uint в случае значений, которые используют только положительный диапазон [0, ∞), без необходимости иметь специальные внутриполосные значения?

ответ

1

Фактический числовой тип для целых чисел в большинстве случаев - int. Например, len(x) и cap(x) возвращают значения int, даже если они тоже не могут быть отрицательными. В большинстве случаев возврат int помогает избежать преобразования типов между различными числовыми типами.

Так что да, Read() мог бы вернуть uint, но это сделало бы его немного более громоздким для работы.

5

Фактический числовой тип для целых чисел - int. Это отчасти потому, что подписанный int overflow является более очевидным. Небольшое переполнение uint заканчивается тем, что выглядит как допустимое значение, но небольшое переполнение подписанного int будет отрицательным и паническим в местах, ожидающих положительное целое число, например. нарезка.

Это важно, потому что вы обычно берете 'n' из Read() и slice 'p' на эту длину.

например.

n, err := a.Read(p) 
p = p[:n] 
processReadData(p) 
Смежные вопросы