Go'da veri türünü eşle / tupla


118

Tour of Go'nun son alıştırmasını yaparken, bir ( string, int) çift kuyruğuna ihtiyacım olduğuna karar verdim . Yeterince kolay:

type job struct {
    url string
    depth int
}

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

Ama bu beni düşündürdü: Go'da yerleşik çift / tuple veri türleri var mı? Bir işlevden birden fazla değer döndürmek için destek vardır , ancak AFAICT, üretilen çoklu değer dizileri Go'nun tür sistemindeki birinci sınıf vatandaşlar değildir. Durum bu mu?

"Ne denediniz" kısmına gelince, açık sözdizimi (bir Python programcısının POV'sinden)

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

işe yaramadı.

Yanıtlar:


57

Go'da tuple türü yoktur ve haklısınız, işlevler tarafından döndürülen birden çok değer birinci sınıf bir nesneyi temsil etmez.

Nick'in cevabı, rastgele türleri kullanan benzer bir şeyi nasıl yapabileceğinizi gösterir interface{}. (Bunu bir demet gibi indekslenebilir hale getirmek için bir yapı yerine bir dizi kullanmış olabilirim, ancak anahtar fikir interface{}türdür)

Diğer cevabım, anonim yapılar kullanarak bir tür oluşturmaktan kaçınan benzer bir şeyi nasıl yapabileceğinizi gösteriyor.

Bu teknikler tuple'ların bazı özelliklerine sahiptir, ancak hayır, tuple değiller.


91

Bunu yapabilirsiniz. Bir demetten daha sözlü görünüyor, ancak bu büyük bir gelişme çünkü yazım denetimi alıyorsunuz.

Düzenleme: Snippet'in önerisini takiben tam bir çalışma örneği ile değiştirilen pasaj. Oyun alanı bağlantısı: 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}
}

Anonim yapılar ve alanlar, bunun gibi hızlı ve kirli çözümler için uygundur. En basit durumlar dışında hepsi için, aynen yaptığınız gibi adlandırılmış bir yapı tanımlamak daha iyi olur.


9
Muhtemelen anonim yapı üyelerinden değerleri nasıl elde edeceğinizi açıklamalısınız çünkü bunun yeni başlayanlar için açık olduğunu düşünmüyorum!
Nick Craig-Wood

9
ancak, aynı türde birden çok alan varsa bu işe yaramayacaktır
newacct

1
Anonim bir yapıda adlandırılmış alanlara sahip olabilirsiniz, yalnızca alanların anonim yapı tanımının göründüğü her yerde aynı şekilde adlandırıldığından emin olmanız gerekir (bu örnekte üç kez) Anonim alanlar, bundan kurtulabilirseniz daha kolaydır .
Sonia

5
Yani cevap "hayır, demet tipi yok" mu?
Fred Foo

37

İstersen böyle bir şey yapabilirsin

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

Bununla birlikte, zaten sahip olduğunuz şeyin tamamen deyimsel olduğunu ve yapı verilerinizi mükemmel bir şekilde tanımladığını düşünüyorum, bu da düz demetler kullanmaya göre büyük bir avantajdır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.