Аналогичные функции, разные типы & hellip; Лучшая практика GoLang, поскольку нет дженериков? [Дубликат]

19
задан Robert 6 June 2011 в 18:26
поделиться

3 ответа

Вы можете сделать это с помощью интерфейсов Go. Функция, которая берет тип интерфейса, является общей в том смысле, что она не заботится о представлении данных базового конкретного типа. Он делает все через вызовы методов.

Чтобы создать общую версию вашего алгоритма, вы должны идентифицировать все возможности, которые требуется алгоритму для объектов данных, и вы должны определить методы, которые абстрагируют эти возможности , Подписи абстрактного метода становятся наборами методов интерфейсов.

Чтобы тип, совместимый с таким универсальным алгоритмом, вы определяете методы типа, чтобы удовлетворить интерфейс параметра алгоритма.

Я возьму ваш пример кода и покажу один способ сделать это. Большинство требуемых возможностей, вероятно, покрываются sort.Interface, поэтому я решил включить его. Требуется только одна возможность: копировать данные.

type algoContainer interface {
    sort.Interface
    Copy() algoContainer
}

Ниже приведена полная рабочая программа, сделанная из вашего примера кода.

package main

import (
    "fmt"
    "sort"
)

func main() {
    s1 := sortableString("abc")
    c1 := Algo(s1)
    fmt.Println(s1, <-c1)

    s2 := sortable3Ints([3]int{1,2,3})
    c2 := Algo(&s2)
    fmt.Println(s2, <-c2)
}

type algoContainer interface {
    sort.Interface
    Copy() algoContainer
}

type sortableString []byte
func (s sortableString) Len() int { return len(s) }
func (s sortableString) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
func (s sortableString) Less(i, j int) bool { return s[i] < s[j] }
func (s sortableString) Copy() algoContainer {
   return append(sortableString{}, s...)
}
func (s sortableString) String() string { return string(s) }

type sortable3Ints [3]int
func (sortable3Ints) Len() int { return 3 }
func (s *sortable3Ints) Swap(i, j int) {
   (*s)[i], (*s)[j] = (*s)[j], (*s)[i]
}
func (s sortable3Ints) Less(i, j int) bool { return s[i] < s[j] }
func (s sortable3Ints) Copy() algoContainer { c := s; return &c }

func Algo(list algoContainer) chan algoContainer {
    n := list.Len()
    out := make(chan algoContainer)
    go func () {
        for i := 0; i < n; i++ {
            result := list.Copy()
            // actually useful:
            if result.Less(n-1, 0) {
                result.Swap(n-1, 0)
            }
            out <- result
        }
        close(out)
    }()
    return out
}
9
ответ дан Sonia 5 September 2018 в 07:35
поделиться

Go не имеет общих типов, но вы можете посмотреть, как sort работает, чтобы найти обходной путь. Что они делают, так это создать такой интерфейс:

type Interface interface {
    // Len is the number of elements in the collection.
    Len() int
    // Less returns whether the element with index i should sort
    // before the element with index j.
    Less(i, j int) bool
    // Swap swaps the elements with indexes i and j.
    Swap(i, j int)
}

И теперь для любого настраиваемого типа вы можете создать соответствующий настраиваемый тип коллекции, который можно отсортировать. Алгоритм сортировки должен иметь дело только с целыми числами и булевыми значениями, и поэтому не видит и не заботится о том, каковы основные типы данных.

6
ответ дан btilly 5 September 2018 в 07:35
поделиться

Поскольку язык программирования Go не поддерживает в настоящее время общие типы, это будет трудно сделать.

Почему у Go нет общих типов?

В какой-то момент вполне могут быть добавлены дженерики. Мы не чувствуем для них неотложности, хотя мы понимаем, что некоторые программисты это делают.

Дженерики удобны, но они сложны по сложности в системе типов и времени выполнения. Мы еще не нашли дизайн, который дает ценность, пропорциональную сложности, хотя мы продолжаем думать об этом. Между тем, встроенные карты и фрагменты Go, а также возможность использования пустого интерфейса для создания контейнеров (с явным распаковкой) означают, что во многих случаях можно написать код, который будет делать какие дженерики будут разрешены, если будет менее плавным.

Это остается открытой проблемой.

Посмотрите на пакет сортировки Go , чтобы увидеть, как он обрабатывает сравнения и другие операции, относящиеся к типу, путем определения sort.Interface с методами Len, Less и Swap.

8
ответ дан peterSO 5 September 2018 в 07:35
поделиться
Другие вопросы по тегам:

Похожие вопросы: