Диапазон Go может перебирать карты и фрагменты, но мне было интересно, есть ли способ перебора диапазона чисел, что-то вроде этого:
for i := range [1..10] {
fmt.Println(i)
}
Или есть способ представить диапазон целых чисел в Go, как это делает Ruby с классом Range ?
Вот программа для сравнения двух предложенных способов
Скомпилируйте как это, чтобы произвести разборку
Здесь ясно (я удалил не инструкции из списка)
настроить
петля
А вот с_iter
настроить
петля
Таким образом, вы можете видеть, что решение iter значительно дороже, хотя оно полностью встроено на этапе установки. В фазе цикла есть дополнительная инструкция в цикле, но это не так уж плохо.
Я бы использовал простой цикл for.
источник
runtime.makeslice
а другое нет - мне не нужен тест, чтобы знать, что он будет намного медленнее!runtime.makeslice
достаточно умно, чтобы не выделять память, если вы просите о выделении нулевого размера. Однако вышеупомянутое все еще называет это, и согласно твоему тесту действительно занимает 10 нс дольше на моей машине.Марк Мишин предложил использовать слайс, но нет смысла создавать массив
make
и использовать его вfor
возвращаемом слайсе, когда массив, созданный с помощью литерала, может быть корочеисточник
for range [5]int{} {
5
здесь это литерал и не может быть определен во время выполнения.iter - очень маленький пакет, который просто обеспечивает синтетически иной способ перебора целых чисел.
Роб Пайк (автор Go) раскритиковал это :
источник
iter
версия на самом деле использует меньше нажатий клавиш , потому чтоrange
иiter
будет автозаполнения.for
циклы не являются первоклассным гражданином Unix, как они в ходу. Кроме того, в отличиеfor
,seq
потоки в стандартный вывод последовательность чисел. Стоит ли перебирать их, зависит от потребителя. Хотяfor i in $(seq 1 10); do ... done
это обычное явление в Shell, это единственный способ сделать цикл for, который сам по себе является единственным способом использования выходных данныхseq
, хотя и очень распространенным.i in range(10)
точно так же, как и раньшеi := 0; i < 10; i++
.Вот тест для сравнения оператора Go
for
с ForClause и оператора Gorange
с использованиемiter
пакета.iter_test.go
Вывод:
источник
Хотя я сожалею о вашей озабоченности отсутствием этой языковой функции, вы, вероятно, просто захотите использовать обычный
for
цикл. И вам, вероятно, будет лучше с этим, чем вы думаете, когда будете писать больше кода на Go.Я написал этот пакет iter - который поддерживается простым идиоматическим
for
циклом, который возвращает значения через achan int
- в попытке улучшить дизайн, найденный на https://github.com/bradfitz/iter , который, как было указано, имеет проблемы с кэшированием и производительностью, а также умная, но странная и не интуитивная реализация. Моя собственная версия работает так же:Однако сравнительный анализ показал, что использование канала было очень дорогим вариантом. Сравнение 3 методов, которые можно запустить
iter_test.go
в моем пакете, используяколичественно показывает, насколько плохо его производительность
В процессе этот тест также показывает, как
bradfitz
решение работает хуже по сравнению со встроеннымfor
предложением для размера цикла10
.Короче говоря, до сих пор не найдено способа дублировать производительность встроенного
for
предложения, в то же время предоставляя простой синтаксис,[0,n)
подобный тому, который есть в Python и Ruby.К сожалению, для команды Go было бы легко добавить в компилятор простое правило для изменения строки, например:
на тот же машинный код, что и
for i := 0; i < 10; i++
.Однако, чтобы быть справедливым, после написания своей собственной
iter.N
(но до сравнительной оценки) я вернулся к недавно написанной программе, чтобы увидеть все места, где я мог ее использовать. Там на самом деле не было много. В неосновной части моего кода было только одно место, где я мог обойтись без более полногоfor
предложения по умолчанию .Таким образом, хотя это может показаться огромным разочарованием для языка в принципе, вы можете обнаружить - как и я - что вам на самом деле это не нужно на практике. Как известно, Роб Пайк говорит о дженериках, вы можете не пропустить эту функцию так сильно, как вы думаете.
источник
Если вы хотите просто перебрать диапазон без использования индексов или чего-либо еще, этот пример кода работал для меня просто отлично. Никакой дополнительной декларации не требуется, нет
_
. Хотя не проверял производительность.PS Самый первый день в GoLang. Пожалуйста, сделайте критику, если это неправильный подход.
источник
non-constant array bound
на меня.Вы также можете проверить github.com/wushilin/stream
Это ленивый поток, похожий на концепцию java.util.stream.
Надеюсь это поможет
источник
источник
Я написал пакет на Голанге, который имитирует функцию диапазона Python:
Пакет https://github.com/thedevsaddam/iter
источник