Язык программирования Go: а где же Generics ?!

Решил тут я недавича совместить полензное-с-полезным, то есть продолжить изучение Go и углубить свои познания в алгоритмах.  Как показали неудачно пройденные интервью, алгоритмы надо знать и не мучаться в поисках ответов на вопросы «что такое o-маленькое и что такое О-большое».  Все мои потуги вылились в проект golang-algoпервоначальная идея проекта — это реализация алгоритмов, описанных в курсе Introduction to Algorithms (SMA 5503)Приглашаю всех желающих присоединиться — не хватает общения с умными и образованными людьми🙂

Ну а теперь к сути проблемы: мой первый insertsort алгоритм был написан для коллекций целочисленных чисел, иначе говоря int. На практике хотелось бы иметь generic алгоритмы,  для коллекций любых элементов, реализующих нечто вроде метода equals, на подобе того, что мы имеем в java.util.Collections:

public static <T> void sort(List<T> list, Comparator<? super T> c)

Прямого аналога Java Generics я в Go не нашел, значит остается единственный путь использовавть в качестве типа элементов коллекции базовый класс, некий object. Но что является object’ом в Go.  Оказывается есть такой тип:

A type implements any interface comprising any subset of its methods and 
may therefore implement several distinct interfaces. For instance, all types
implement the empty interface:
interface{}


Иначе говоря interface{}  это и есть базовый класс для всех типов. Тогда сигнатура нашего метода sort  будет выглядеть как:

 func InsertionSort(input []interface{}, eq Equals) {
}

где eq — это компаратор (по сути указатель на функцию), реализующий метод equals

type Equals func (arg0 interface{}, arg1 interface{}) int

Как же все это бут выглядеть для int ? Попытка напрямую передать маасив int обернулась полным крахом, компилятор честно предупредил, что int не явялется типом и не может быть приведен к interface{}.  Тогда начинаем хитрить (тип rune в Go синоним int):

type Rune rune
func equalsRune(arg0 interface{}, arg1 interface{}) int{
 runeArg0, runeArg1 := arg0.(Rune), arg1.(Rune);
 if runeArg0 < runeArg1 {
 return -1;
 } else if runeArg0 == runeArg1 {
 return 0;
 }
 return 1;
}

И мы уже смело можем сортировать целочисленный массив:

input := []interface{}{Rune(4),  Rune(3),  Rune(2),  Rune(1),  Rune(0)};
InsertionSort(input,equalsRune)

Ну сами понимаете, что на месте int может оказаться и любой другой тип, достаточно описать только метод equals.

Более детально ознакомиться как с реализацией «Generics», так и собственно с реализацией алгоримтов вы можете здесь. Как всегда буду рад любой критике и комментариям😉


		
Отмечено

Добавить комментарий

Заполните поля или щелкните по значку, чтобы оставить свой комментарий:

Логотип WordPress.com

Для комментария используется ваша учётная запись WordPress.com. Выход / Изменить )

Фотография Twitter

Для комментария используется ваша учётная запись Twitter. Выход / Изменить )

Фотография Facebook

Для комментария используется ваша учётная запись Facebook. Выход / Изменить )

Google+ photo

Для комментария используется ваша учётная запись Google+. Выход / Изменить )

Connecting to %s

%d такие блоггеры, как: