Метод для обработки разных типов данных - PullRequest
0 голосов
/ 05 июля 2019

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

func GetRandomSubarrayInt64(candidates []int64, length int) []int64 {
    result := make([]int64, 0, length)
    if len(candidates) == 0 {
        return result
    }
    if len(candidates) <= length {
        return candidates
    }
    rand.Shuffle(len(candidates), func(i, j int) {
        candidates[i], candidates[j] = candidates[j], candidates[i]
    })
    return candidates[:length]
}


func GetRandomSubarrayString(candidates []string, length int) []string {
    result := make([]string, 0, length)
    if len(candidates) == 0 {
        return result
    }
    if len(candidates) <= length {
        return candidates
    }
    rand.Shuffle(len(candidates), func(i, j int) {
        candidates[i], candidates[j] = candidates[j], candidates[i]
    })
    return candidates[:length]
}

Код почти повторяется. Есть ли способ уменьшить дублирующийся код?

Ответы [ 2 ]

0 голосов
/ 05 июля 2019

Вы можете определить интерфейс, который экспортирует методы для обмена элементами в базовом массиве. Затем вам нужно будет реализовать этот интерфейс с вашим типом массива / среза. Что-то вроде это .

type ShuffleSlice interface {
    Swap(i, j int)
    Len() int
}

func GetRandomSubslice(candidates ShuffleSlice) ShuffleSlice {
    if candidates == nil || candidates.Len() == 0 {
        return nil
    }
    rand.Shuffle(candidates.Len(), func(i, j int) {
        candidates.Swap(i, j)
    })
    return candidates
}

type ShuffleSliceInt []int

func (s ShuffleSliceInt) Swap(i, j int) {
    s[i], s[j] = s[j], s[i]
}

func (s ShuffleSliceInt) Len() int {
    return len(s)
}
0 голосов
/ 05 июля 2019

Да, Golang сейчас не поддерживает Generics.

Но вы можете попробовать так:

func GetRandomSubarray(candidates interface{}, length int) interface{} {
    candidatesValue := reflect.ValueOf(candidates)
    if candidatesValue.Kind() != reflect.Slice {
        panic("supports slice only")
    }
    if candidatesValue.Len() == 0 {
        return candidates
    }
    if candidatesValue.Len() <= length {
        return candidates
    }
    rand.Shuffle(candidatesValue.Len(), reflect.Swapper(candidates))
    return candidatesValue.Slice(0, length).Interface()
}

Использование:

s := []string{"1", "2", "3"}
rs := GetRandomSubarray(s, 1).([]string)

i := []int{1, 2, 3}
ri := GetRandomSubarray(i, 1).([]int)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...