При написании универсальных функций в 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