Co to jest zwięzły sposób na stworzenie plasterka 2D w Go?

Uczę się Go, przechodząc przezwycieczkę Go . Jedno z ćwiczeń prosi mnie o stworzenie 2D wycinka dy wierszy i dx kolumn zawierających uint8. Moje obecne podejście, które działa, jest takie:

a:= make([][]uint8, dy)       // initialize a slice of dy slices
for i:=0;i<dy;i++ {
    a[i] = make([]uint8, dx)  // initialize a slice of dx unit8 in each of dy slices
}

Myślę, że iteracja każdego kawałka w celu zainicjowania jest zbyt gadatliwa. A gdyby kawałek miał więcej wymiarów, kod stałby się nieporęczny. Czy istnieje zwięzły sposób inicjalizacji plastrów 2D (lub N-wymiarowych) w Go?

 27
Author: hazrmard, 2016-10-01

2 answers

Nie ma bardziej zwięzłego sposobu, to co zrobiłeś jest "właściwym" sposobem; ponieważ plasterki są zawsze jednowymiarowe, ale mogą być komponowane do konstruowania obiektów wyższych wymiarów. Zobacz to pytanie po więcej szczegółów: idź: jak wygląda reprezentacja pamięci tablicy dwuwymiarowej .

Jedną rzeczą, którą można uprościć, jest użycie for range konstrukcji:

a := make([][]uint8, dy)
for i := range a {
    a[i] = make([]uint8, dx)
}

Zauważ również, że jeśli zainicjalizujesz swój kawałek za pomocą composite literal , otrzymasz to za "free", za przykład:

a := [][]uint8{
    {0, 1, 2, 3},
    {4, 5, 6, 7},
}
fmt.Println(a) // Output is [[0 1 2 3] [4 5 6 7]]

Tak, ma to swoje granice, ponieważ pozornie musisz wyliczyć wszystkie elementy; ale są pewne sztuczki, mianowicie nie musisz wyliczać wszystkich wartości, tylko te, które nie są wartościami zerowymi typu elementu wycinka. Aby uzyskać więcej informacji na ten temat, zobacz Keyed items in golang array initialization.

Na przykład, jeśli chcesz wycinek, w którym pierwsze 10 elementów jest zerami, a następnie 1 i 2, można go utworzyć w następujący sposób to:

b := []uint{10: 1, 2}
fmt.Println(b) // Prints [0 0 0 0 0 0 0 0 0 0 1 2]

Zauważ również, że jeśli użyjesz tablic zamiast plastrów , można ją bardzo łatwo utworzyć:

c := [5][5]uint8{}
fmt.Println(c)

Wyjście to:

[[0 0 0 0 0] [0 0 0 0 0] [0 0 0 0 0] [0 0 0 0 0] [0 0 0 0 0]]

W przypadku tablic nie trzeba iteracji nad" zewnętrzną "tablicą i inicjalizacji tablic "wewnętrznych", ponieważ tablice nie są deskryptorami, lecz wartościami. Zobacz wpis na blogu Tablice, plasterki (i łańcuchy): mechanika 'append' aby uzyskać więcej szczegółów.

Wypróbuj przykłady na Go Playground.

 45
Author: icza,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:02:56

Możesz odnieść się do tego fragmentu kodu -

package main

import "fmt"

func main() {
    var row, col int
    fmt.Print("enter rows cols: ")
    fmt.Scan(&row, &col)

    // allocate composed 2d array
    a := make([][]int, row)
    for i := range a {
        a[i] = make([]int, col)
    }

    // array elements initialized to 0
    fmt.Println("a[0][0] =", a[0][0])

    // assign
    a[row-1][col-1] = 7

    // retrieve
    fmt.Printf("a[%d][%d] = %d\n", row-1, col-1, a[row-1][col-1])

    // remove only reference
    a = nil
    // memory allocated earlier with make can now be garbage collected.
}

Odniesienie

 0
Author: Techidiot,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-01 09:28:42