2012-12-02 30 views
50

Khi thực hiện final exercise of the Tour of Go, tôi quyết định tôi cần một hàng đợi (string, int) cặp. Điều đó thật dễ dàng:Loại dữ liệu cặp/tuple trong Go

type job struct { 
    url string 
    depth int 
} 

queue := make(chan job) 
queue <- job{url, depth} 

Nhưng điều này khiến tôi nghĩ: có các kiểu dữ liệu cặp/tuple tích hợp trong Go? Có hỗ trợ cho returning multiple values từ một hàm, nhưng AFAICT, các giá trị nhiều bộ dữ liệu được tạo ra không phải là công dân hạng nhất trong hệ thống kiểu của Go. Đó là trường hợp?

Đối với "những gì đã bạn đã cố gắng" một phần, cú pháp rõ ràng (từ POV một Python lập trình viên của)

queue := make(chan (string, int)) 

đã không làm việc.

Trả lời

23

Không có loại tuple trong Go và bạn đúng, nhiều giá trị được trả về bởi hàm không đại diện cho đối tượng lớp đầu tiên.

Câu trả lời của Nick cho thấy cách bạn có thể làm điều gì đó tương tự xử lý các loại tùy ý bằng giao diện {}. (Tôi có thể đã sử dụng một mảng thay vì cấu trúc để làm cho nó có thể lập chỉ mục như một bộ tẩu, nhưng ý tưởng chính là loại giao diện {}.)

Câu trả lời khác của tôi cho thấy cách bạn có thể làm một việc tương tự sử dụng cấu trúc ẩn danh.

Những kỹ thuật này có một số thuộc tính của bộ dữ liệu, nhưng không, chúng không phải là bộ dữ liệu.

54

Bạn có thể thực hiện việc này. Trông nó dài hơn một tuple, nhưng đó là một cải tiến lớn bởi vì bạn kiểm tra kiểu.

Chỉnh sửa: Đoạn mã được thay thế bằng ví dụ hoạt động hoàn chỉnh, theo đề xuất của Nick. Liên kết sân chơi: http://play.golang.org/p/RNx_otTFpk

package main 

import "fmt" 

func main() { 
    queue := make(chan struct {string; int}) 
    go sendPair(queue) 
    pair := <-queue 
    fmt.Println(pair.string, pair.int) 
} 

func sendPair(queue chan struct {string; int}) { 
    queue <- struct {string; int}{"http:...", 3} 
} 

Cấu trúc ẩn danh và trường là tốt cho các giải pháp nhanh và bẩn như thế này. Đối với tất cả, nhưng các trường hợp đơn giản nhất mặc dù, bạn sẽ làm tốt hơn để xác định một struct được đặt tên giống như bạn đã làm.

+7

Bạn có lẽ nên mô tả cách lấy các giá trị ra khỏi thành viên cấu trúc ẩn danh vì tôi không nghĩ rằng điều đó hiển nhiên đối với người mới bắt đầu! –

+6

tuy nhiên, điều này sẽ không hoạt động nếu có nhiều trường có cùng kiểu – newacct

+1

Bạn có thể có các trường có tên trong cấu trúc ẩn danh, bạn chỉ cần đảm bảo rằng các trường được đặt tên theo cùng một cách mà mỗi định nghĩa struct ẩn danh xuất hiện (ba lần trong ví dụ này.) Các trường ẩn danh dễ dàng hơn nếu bạn có thể thoát khỏi nó. – Sonia

15

Bạn có thể làm một cái gì đó như thế này nếu bạn muốn

package main 

import "fmt" 

type Pair struct { 
    a, b interface{} 
} 

func main() { 
    p1 := Pair{"finished", 42} 
    p2 := Pair{6.1, "hello"} 
    fmt.Println("p1=", p1, "p2=", p2) 
    fmt.Println("p1.b", p1.b) 
    // But to use the values you'll need a type assertion 
    s := p1.a.(string) + " now" 
    fmt.Println("p1.a", s) 
} 

Tuy nhiên tôi nghĩ rằng những gì bạn đã là hoàn thành ngữ và các cấu trúc mô tả dữ liệu của bạn một cách hoàn hảo mà là một lợi thế lớn so với sử dụng các bộ đơn giản.

Các vấn đề liên quan