2013-09-29 52 views
21

Tôi mới dùng Go và cố gắng viết một ứng dụng đọc các tệp RPM. Sự bắt đầu của mỗi khối có một Magic char là [4]byte.Trong Golang, làm thế nào để bạn chuyển đổi một slice thành một mảng

Đây là struct tôi

type Lead struct { 
    Magic  [4]byte 
    Major, Minor byte 
    Type   uint16 
    Arch   uint16 
    Name   string 
    OS   uint16 
    SigType  uint16 
} 

Tôi cố gắng để làm như sau:

lead := Lead{} 
lead.Magic = buffer[0:4] 

tôi đang tìm kiếm trực tuyến và không chắc chắn làm thế nào để đi từ một lát để một mảng (không sao chép) . Tôi luôn có thể làm cho Magic []byte (hoặc thậm chí uint64), nhưng tôi tò mò hơn về cách tôi sẽ đi từ loại []byte đến [4]byte nếu cần thiết?

+1

Có một cuộc tranh luận gần đây về việc liệu nó có nên được phép chia thành một mảng hay không. Các kết quả không có kết quả, một cái gì đó giống như những gì bạn muốn có thể được thêm vào trong tương lai. Hãy nhớ rằng [4] byte là một đối tượng và không phải là một con trỏ tới một đối tượng. Điều duy nhất có thể là gán cho một con trỏ tới một mảng. – fuz

+0

https://play.golang.org/p/ulk0kmJzf6 –

Trả lời

27

Việc xây dựng trong phương pháp sao chép sẽ chỉ sao chép một lát để một lát KHÔNG một lát để một mảng.

Bạn phải lừa bản sao vào suy nghĩ mảng là một lát

copy(varLead.Magic[:], someSlice[0:4]) 

Hoặc sử dụng một vòng lặp for để làm bản sao:

for index, b := range someSlice { 

    varLead.Magic[index] = b 

} 

Hoặc làm như Zupa đã thực hiện bằng chữ. Tôi đã thêm vào ví dụ làm việc của họ.

Go Playground

+1

làm [0: 3] sẽ chỉ sao chép 3 phần tử đầu tiên, không phải tất cả bốn phần tử. như được đề xuất khác, làm [0: 4] – galaktor

+1

Bạn cũng có thể sử dụng 'copy (varLead.Magic [:], someSlice [:])'. Điều này sẽ sao chép tất cả nội dung phù hợp với mảng. – Pascal

+2

Cũng chỉ 'copy (varLead.Magic [:], someSlice)' là đủ vì nó sẽ chỉ sao chép nội dung phù hợp với mảng. – shebaw

10

Bạn đã phân bổ bốn byte bên trong cấu trúc đó và muốn chỉ định giá trị cho phần bốn byte đó. Không có cách khái niệm để làm điều đó mà không cần sao chép.

Nhìn vào số copy được cài sẵn để biết cách thực hiện điều đó.

6

Hãy thử điều này:

copy(lead.Magic[:], buf[0:4]) 
-4

Không. Slice chính nó là đủ cho tất cả các mục đích. Mảng trong go lang nên được coi là cấu trúc cơ bản của slice. Trong mọi trường hợp, chỉ sử dụng slice. Bạn không cần phải tự mảng. Bạn chỉ cần làm mọi thứ theo cú pháp slice. Mảng chỉ dành cho máy tính. Trong hầu hết các trường hợp, lát là tốt hơn, rõ ràng trong mã. Ngay cả trong các trường hợp khác, lát vẫn đủ để phản xạ ý tưởng của bạn.

+1

Trong các slice * chung * có thể được ưu tiên hơn mảng nhưng có những nơi mà mảng thích hợp và cao cấp.Nói "Trong mọi trường hợp, chỉ sử dụng slice" là sai. –

+2

Ví dụ về mảng cần thiết: là thành viên của cấu trúc phải được so sánh (ví dụ: để sử dụng cấu trúc đó làm khóa bản đồ). –

0

Bạn có thể thực hiện toàn bộ nội dung bằng một lần đọc, thay vì đọc riêng từng trường. Nếu các trường có độ dài cố định, thì bạn có thể làm:

lead := Lead{} 

// make a reader to dispense bytes so you don't have to keep track of where you are in buffer 
reader := bytes.NewReader(buffer) 

// read into each field in Lead, so Magic becomes buffer[0:4], 
// Major becomes buffer[5], Minor is buffer[6], and so on... 
binary.Read(reader, binary.LittleEndian, &lead) 
Các vấn đề liên quan