Files
2026-07-13 12:49:10 +08:00

91 lines
2.2 KiB
Go

/*
* Copyright 2024 CloudWeGo Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package generic
import (
"reflect"
)
// NewInstance create an instance of the given type T.
// the main purpose of this function is to create an instance of a type, can handle the type of T is a pointer or not.
// eg. NewInstance[int] returns 0.
// eg. NewInstance[*int] returns *0 (will be ptr of 0, not nil!).
func NewInstance[T any]() T {
typ := TypeOf[T]()
switch typ.Kind() {
case reflect.Map:
return reflect.MakeMap(typ).Interface().(T)
case reflect.Slice, reflect.Array:
return reflect.MakeSlice(typ, 0, 0).Interface().(T)
case reflect.Ptr:
typ = typ.Elem()
origin := reflect.New(typ)
inst := origin
for typ.Kind() == reflect.Ptr {
typ = typ.Elem()
inst = inst.Elem()
inst.Set(reflect.New(typ))
}
return origin.Interface().(T)
default:
var t T
return t
}
}
// TypeOf returns the type of T.
// eg. TypeOf[int] returns reflect.TypeOf(int).
// eg. TypeOf[*int] returns reflect.TypeOf(*int).
func TypeOf[T any]() reflect.Type {
return reflect.TypeOf((*T)(nil)).Elem()
}
// PtrOf returns a pointer of T.
// useful when you want to get a pointer of a value, in some config, for example.
// eg. PtrOf[int] returns *int.
// eg. PtrOf[*int] returns **int.
func PtrOf[T any](v T) *T {
return &v
}
type Pair[F, S any] struct {
First F
Second S
}
// Reverse returns a new slice with elements in reversed order.
func Reverse[S ~[]E, E any](s S) S {
d := make(S, len(s))
for i := 0; i < len(s); i++ {
d[i] = s[len(s)-i-1]
}
return d
}
// CopyMap copies a map to a new map.
func CopyMap[K comparable, V any](src map[K]V) map[K]V {
dst := make(map[K]V, len(src))
for k, v := range src {
dst[k] = v
}
return dst
}