Пара даних / тип даних у Go


118

Роблячи остаточне здійснення туру Го , я вирішив , що я потребував черзі ( string, int) пара. Це досить просто:

type job struct {
    url string
    depth int
}

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

Але це задумало мене: чи є вбудовані типи даних пари / кортежі в Go? Існує підтримка повернення декількох значень з функції, але AFAICT, створені кортежі з декількома значеннями не є громадянами першого класу в системі типу Go. Це так?

Що стосується частини "що ви спробували", очевидний синтаксис (від POV програміста Python)

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

не працювало.

Відповіді:


57

У режимі Go немає типу кортежу, і ви правильно, численні значення, повернені функціями, не являють собою об'єкт першого класу.

Відповідь Ніка показує, як можна зробити щось подібне, що обробляє довільні типи, використовуючи interface{}. (Я, можливо, використовував масив, а не структуру, щоб зробити його покажчивим як кортеж, але ключовою ідеєю є interface{}тип)

Інша моя відповідь показує, як ви можете зробити щось подібне, що уникає створення типу за допомогою анонімних структур.

Ці прийоми мають деякі властивості кортежів, але ні, вони не кортежі.


91

Ви можете це зробити. Це виглядає більш багатослівно, ніж кортеж, але це велике поліпшення, тому що ви отримуєте перевірку типу.

Редагувати: замінено фрагмент на повний робочий приклад, виконуючи пропозицію Ніка. Посилання на майданчик: 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}
}

Анонімні структури та поля чудово підходять для швидких та брудних рішень, як це. Хоча для всіх, крім найпростіших випадків, краще визначити структуру з назвою так само, як і ви.


9
Вам, мабуть, слід описати, як вивести значення з анонімних членів структури, тому що я не думаю, що для початківців це очевидно!
Нік Крейг-Вуд

9
однак це не буде працювати, якщо є кілька полів одного типу
newacct

1
Ви можете назвати поля в анонімній структурі, ви просто повинні переконатися, що поля названі однаково, коли кожне місце з'являється визначення анонімної структури (три рази в цьому прикладі.) Анонімні поля простіші, якщо ви можете піти з ним .
Соня

5
Отже, відповідь "ні, немає типу кортежу"?
Фред Фоо

37

Ви могли б зробити щось подібне, якби хотіли

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

Однак я думаю, що у вас вже є ідеальне слово, і структура чудово описує ваші дані, що є великою перевагою перед використанням простих кортежів.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.