«Если рабочий хочет хорошо выполнять свою работу, он должен сначала заточить свои инструменты» — Конфуций, «Аналитики Конфуция. Лу Лингун»
титульная страница > программирование > ## Как инициализировать фрагменты интерфейсов с конкретными типами в Go?

## Как инициализировать фрагменты интерфейсов с конкретными типами в Go?

Опубликовано 10 ноября 2024 г.
Просматривать:105

## How to Initialize Slices of Interfaces with Concrete Types in Go?

Общая инициализация с интерфейсами и конкретными типами в Go

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

Первоначальные попытки с несколькими параметрами типа

Один подход может показаться логичным: определение двух параметров типа, один для типа элемента среза (X) и один для конкретного типа (Y), экземпляр которого необходимо создать. Однако этот подход терпит неудачу при попытке назначить экземпляр Y элементу типа X.

func Fill[X, Y any](slice []X){
   for i := range slice {
      slice[i] = new(Y) // not work!
   }
}

Эта проблема возникает из-за того, что компилятор теряет связь между интерфейсом X и его реализацией Y. И X, и Y считаются разными типами.

Использование явного приведения типов

Чтобы решить эту проблему, можно использовать явную операцию приведения внутри функции:

func Fill[X, Y any](slice []X) {
    for i := range slice {
        slice[i] = any(*new(Y)).(X)
    }
}

Однако этот подход вызывает панику, если Y не реализует X, что происходит в таких сценариях, как попытка назначить *sync.Mutex (тип указателя) для sync.Locker.

Использование функции конструктора

Более надежное и типобезопасное решение предполагает использование конструктора. function:

func Fill[X any](slice []X, f func() X) {
    for i := range slice {
        slice[i] = f()
    }
}

Эта функция принимает функцию-конструктор, которая возвращает новый экземпляр указанного типа. Это обеспечивает краткую и безопасную инициализацию срезов с экземплярами конкретного типа.

Избегание нулевых значений

В случаях, когда конкретный тип предназначен для создания экземпляра с типом указателя, важно отметить этот new(Y) приведет к нулевому значению. Чтобы обойти это, можно настроить функцию-конструктор так, чтобы она возвращала правильное значение указателя, например func() X { return &sync.Mutex{} }.

Последний учебник Более>

Изучайте китайский

Отказ от ответственности: Все предоставленные ресурсы частично взяты из Интернета. В случае нарушения ваших авторских прав или других прав и интересов, пожалуйста, объясните подробные причины и предоставьте доказательства авторских прав или прав и интересов, а затем отправьте их по электронной почте: [email protected]. Мы сделаем это за вас как можно скорее.

Copyright© 2022 湘ICP备2022001581号-3