2016-10-01 28 views
15

Öğrenmeyi A Tour of Go üzerinden geçerek öğreniyorum. Buradaki alıştırmalardan biri bana dy satırlık bir 2D dilimi ve uint8 içeren dx sütunları oluşturmamı ister.Go'da bir 2D dilim oluşturmanın kısa bir yolu nedir?

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 
} 

Ben her dilimin yineleme çok ayrıntılı olduğunu başlatmak için olduğunu düşünüyorum: çalışan Beni şimdiki yaklaşım, bu. Ve dilim daha fazla boyutlara sahip olsaydı, kod hantal hale gelirdi. Go'da 2D (veya n boyutlu) dilimleri başlatmanın kısa bir yolu var mı?

cevap

25

, yaptığın "doğru" yoludur; çünkü dilimler her zaman tek boyutludur, ancak yüksek boyutlu nesneler oluşturmak için oluşturulabilir. Daha fazla bilgi için bu soruya bakın: Go: How is two dimensional array's memory representation. örneğin,

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

Ayrıca bir composite literal ile dilim başlatmak eğer, "ücretsiz" için bu olsun unutmayın: Eğer buna kolaylaştırabilirsiniz

bir şey for range yapısını kullanmaktır

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

Evet, bu, tüm öğeleri sıralamak zorunda gibi görünen sınırları var; ama bazı hileler vardır, yani tüm değerleri numaralandırmak zorunda değilsiniz, sadece dilim öğesinin türünde zero values olmayanlar. Bununla ilgili daha fazla bilgi için, bkz. Keyed items in golang array initialization.

ilk 10 element sıfırlar olan bir dilim istiyorum, ve sonra 1 ve 2 aşağıdaki Örneğin

, böyle oluşturulabilir:

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

Ayrıca not yerine arrays kullanmayı tercih ederseniz o slices nedeniyle, çok kolay oluşturulabilir:

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

Çıktı geçerli:

[[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]] 

Dizilerde "dış" dizisi üzerinde yineleme yapmak ve "iç" dizileri başlatmak zorunda kalmazsınız, diziler tanımlayıcılar değil, değerlerdir. Daha fazla bilgi için blog gönderisi Arrays, slices (and strings): The mechanics of 'append''a bakın.

Go Playground'daki örnekleri deneyin. Bir 2D dizinin satırlarını takas için bu fonksiyonu yazdım

0

Sen Bu kod parçasını başvurabilirsiniz - Daha özlü bir yolu yoktur

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. 
} 

Reference

+3

'range' yanında ben OP ne sordu farkını ve örnek kodu görmek için başarısız. – eduncan911

-1

:

func lchange(l1 int, l2 int, a [][]float64) { 
    b := make([]float64, 1) 
    b = a[l1][:] 
    a[l1] = a[l2] 
    a[l2] = b 
} 
+0

Bu, soruyla ilgili değil. – hazrmard