Чи є foreach
конструкція мовою Go? Чи можу я повторити фрагмент або масив за допомогою for
?
range
в for
циклах також згадується в «інтерлюдія про Types» (розділ до його кінця) підручника Go.
Чи є foreach
конструкція мовою Go? Чи можу я повторити фрагмент або масив за допомогою for
?
range
в for
циклах також згадується в «інтерлюдія про Types» (розділ до його кінця) підручника Go.
Відповіді:
https://golang.org/ref/spec#For_range
Оператор "для" з пунктом "діапазон" повторюється через усі записи масиву, фрагмента, рядка або карти або значень, отриманих на каналі. Для кожного запису він присвоює значення ітерації відповідним змінним ітерації, а потім виконує блок.
Як приклад:
for index, element := range someSlice {
// index is the index where we are
// element is the element from someSlice for where we are
}
Якщо вам не важливий індекс, ви можете використовувати _
:
for _, element := range someSlice {
// element is the element from someSlice for where we are
}
Підкреслення,, _
- це порожній ідентифікатор , анонімний заповнювач місця.
element
є значення елемента (копія) - це не сам елемент. Хоча ви можете призначити це element
, це не вплине на основну послідовність.
_()
в локальному просторі імен» , який тільки за згодою , це не є частиною локалізації Lib. Підкреслення _
є дійсною міткою, і це також умовні позначення в Go (і Python, Scala та інших язиках), призначені _
для повернутих значень, які ви не будете використовувати. Обсяг _
цього прикладу обмежений тілом for
петлі. Якщо у вас є функція, _
що охоплює пакет, то вона буде затінена всередині циклу for. Є кілька пакетів для локалізації, я не бачив жодного використання _
як імені функції.
Go має foreach
синтаксис -подібний. Він підтримує масиви / фрагменти, карти та канали.
Ітерація через масив або фрагмент :
// index and value
for i, v := range slice {}
// index only
for i := range slice {}
// value only
for _, v := range slice {}
Ітерація над картою :
// key and value
for key, value := range theMap {}
// key only
for key := range theMap {}
// value only
for _, value := range theMap {}
Ітерація через канал :
for v := range theChan {}
Ітерація через канал еквівалентна прийому від каналу до його закриття:
for {
v, ok := <-theChan
if !ok {
break
}
}
chan
використання: перехід через канал витончено вийде з циклу, якщо автор закриє канал у якийсь момент. У for {v := <-theChan}
еквіваленті він не буде виходити на канал закритий. Ви можете перевірити це через друге ok
повернене значення. ПРИКЛАД ТУРУ
for { ... }
означає нескінченну петлю.
Наступний приклад показує, як використовувати range
оператор у for
циклі для реалізації foreach
циклу.
func PrintXml (out io.Writer, value interface{}) error {
var data []byte
var err error
for _, action := range []func() {
func () { data, err = xml.MarshalIndent(value, "", " ") },
func () { _, err = out.Write([]byte(xml.Header)) },
func () { _, err = out.Write(data) },
func () { _, err = out.Write([]byte("\n")) }} {
action();
if err != nil {
return err
}
}
return nil;
}
Приклад повторює масив функцій для уніфікації обробки помилок для функцій. Повний приклад - на дитячому майданчику Google .
PS: це також показує, що підвісні брекети є поганою ідеєю для читабельності коду. Підказка: for
умова закінчується безпосередньо перед action()
викликом. Очевидно, чи не так?
,
і зрозуміліше, де for
закінчується умова: play.golang.org/p/pcRg6WdxBd - Це фактично перший раз, коли я знайшов протилежний аргумент go fmt
стилю, дякую!
Фактично ви можете використовувати range
без посилання на його повернені значення, використовуючи for range
проти свого типу:
arr := make([]uint8, 5)
i,j := 0,0
for range arr {
fmt.Println("Array Loop",i)
i++
}
for range "bytes" {
fmt.Println("String Loop",j)
j++
}
Далі наведено приклад коду того, як використовувати foreach у голангу
package main
import (
"fmt"
)
func main() {
arrayOne := [3]string{"Apple", "Mango", "Banana"}
for index,element := range arrayOne{
fmt.Println(index)
fmt.Println(element)
}
}
Це запущений приклад https://play.golang.org/p/LXptmH4X_0
Так, дальність :
Форма діапазону циклу для циклу повторюється над фрагментом або картою.
У діапазоні відрізка повертаються два значення для кожної ітерації. Перший - індекс, а другий - копія елемента в цьому індексі.
Приклад:
package main
import "fmt"
var pow = []int{1, 2, 4, 8, 16, 32, 64, 128}
func main() {
for i, v := range pow {
fmt.Printf("2**%d = %d\n", i, v)
}
for i := range pow {
pow[i] = 1 << uint(i) // == 2**i
}
for _, value := range pow {
fmt.Printf("%d\n", value)
}
}
Це може бути очевидним, але ви можете вбудувати масив так:
package main
import (
"fmt"
)
func main() {
for _, element := range [3]string{"a", "b", "c"} {
fmt.Print(element)
}
}
Виходи:
abc