Рубрика «generics»

Если вы только начинаете изучать Python и слышите слово дженерики, скорее всего в голове сразу каша: «что это вообще такое?». На самом деле дженерики - это очень простая идея. Представьте, что у вас есть коробка. В коробку можно положить игрушки, яблоки, книжки - всё что угодно.

Но иногда вы хотите, чтобы в коробкележали только яблоки. А иногда — только игрушки. И вот тут вам помогают generics.

Что такое generics?

Читать полностью »

В теории типов вариантность описывает отношение между двумя обобщёнными типами (дженериками). Например, в каких обстоятельствах родительский тип может быть заменён дочерним, а в каких — нет, и так далее.

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

Ковариантность

Отношение ковариантности представляет собой обычное отношение подтипа, когда более Узкий/ДочернийЧитать полностью »

Паттерны типизации в TypeScript напрямую влияют на технический долг — накопление неоптимального кода (костылей), которое замедляет разработку, увеличивает риски ошибок и повышает затраты на поддержку. Осознанный выбор паттерна минимизирует эти проблемы, обеспечивая предсказуемость и масштабируемость кода, что ускоряет адаптацию новых разработчиков и сокращает время на отладку. Ниже приведены исходные типы для дальнейшей демонстрации.

Читать полностью »

В некотором царстве, в некотором государстве жил был царь. Как-то раз объявил царь всему народу - "Кто решит три моих задачки, тот сам сможет царём стать". И даже контракт метода опубликовал, всё честь по чести.

public interface ЦарёвУказ1844 {

  interface РешилВсеЗадачи {}

  void setЦарь(Человек<? extends РешилВсеЗадачи> новыйЦарь);
  Человек<?> getЦарь();
}

Пришёл к царю кузнец, в разных делах дока, и говорит: "Давай свои задачки"

Царь руки потирает и говорит: "Ну что ж, изволь. Вот моя первая задачка"

Задача о боровиках

Читать полностью »

Получение generic-типа в runtime - 1

В Java 5 появились generic-типы, а вместе с ним и концепция type erasure, которая буквально означает стирание информации о generic-типе после компиляции. Действительно, во многих случаях это просто синтаксический сахар, помогающий писать типо-безопасный код на уровне компиляции, и в runtime с такими типами работать нельзя. Например, невозможно получить тип T внутри ArrayList<T>, поэтому он в своей реализации создает массив Object[], а не T[] для хранения элементов.

Однако, в ряде случаев это очень даже возможно. Например, можно объявить поле

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanPostProcessor;
...
@Autowired
private Set<BeanPostProcessor> beanPostProcessors;

и spring в него заинжектит все объекты контекста, которые реализуют интерфейс BeanPostProcessor.

Можно написать и так:

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
...
List<String> strings = new ObjectMapper()
     .readValue("[1, 2, 3]", new TypeReference<>() {});
// все элементы strings - строки (не Integer и не Long)
List<Integer> ints = new ObjectMapper()
     .readValue("[1, 2, 3]", new TypeReference<>() {});
// все элементы ints - Integer (не String и не Long)

Можно написать даже так:
Читать полностью »

Скоро выйдет релиз 1.18 в котором появятся долгожданные дженерики. Они позволят сделать универсальные методы. Я написал пару примеров для себя. Может быть они будут интересны кому-нибудь ещё.

Интерфейсы any, comparable, constraints. и ~

Появились новые ключевые слова

any - аналог interface{}. Это ключевое слово можно использовать в любом месте. Например при определении типа переменной или при опрредении типа поля в структуре. Вот такой код ошибок не вызовет:

func TestDo(v any) any {
	var k any

	k = 10

	return k
}

type Test interface {
	Some() any
}

comparableЧитать полностью »

Как LINQ, только быстрый и без аллокаций - 1

Кому не нравится LINQ в C#? Встроенная и уже достаточно старая фича языка C# и рантайма .NET.

Но можем ли мы сделать более эффективную версию этой фичи?

TL;DR (спойлер)

Можем сделать более эффективную, но намного менее универсальную. Github проекта.

Читать полностью »

PHP Generics. Right here. Right now - 1

Многие PHP разработчики хотели бы видеть в PHP поддержку дженериков, и я в том числе. RFC по их добавлению был создан ещё в 2016 году, но до сих пор не принял окончательный вид. Я рассмотрел несколько вариантов решений поддержки дженериков в синтаксисе PHP, но не нашёл рабочей версии, которой мог бы воспользоваться обычный разработчик.

В итоге я решил, что могу сам попробовать реализовать такое решение на PHP. Скриншот выше — реальный пример того, что у меня получилось.

Если хочется сразу попробовать, то вот библиотека mrsuh/php-generics и репо, в котором можно поиграться.

Читать полностью »

func Map[F, T any](s []F, f func(F) T) []T {
    r := make([]T, len(s))
    for i, v := range s {
        r[i] = f(v)
    }
    return r
}

Как вы уже наверняка знаете, proposal по дженерикам в Golang принят (официально это называется type parameters) и будет имплементирован в go 1.18. Бета будет доступна уже в конце этого года. А это значит, что пора разобраться, на чём в итоге остановились разработчики языка — ведь черновик type parameters постоянно менялся в течение последних лет.

Технология новая, на практике толком никто не использовал. Поэтому если увидите какую-то неточность в статье, не стесняйтесь указать это в комментариях.

Самостоятельно поиграться с дженериками можно здесь

Итак, поехали.

Читать полностью »


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js