Skip to content
This repository has been archived by the owner on Feb 22, 2023. It is now read-only.

Decide on use of type parameters #5

Open
neild opened this issue Dec 14, 2021 · 1 comment
Open

Decide on use of type parameters #5

neild opened this issue Dec 14, 2021 · 1 comment

Comments

@neild
Copy link
Contributor

neild commented Dec 14, 2021

We could use type parameters in the cpy API in a few places.

func Func[T any](fn func(T) T) Option { ... }

Func could be parameterized on the copied type, ensuring that the copy function has the right number of parameters and that the input and output match. However, we cannot fully express the constraints on T using 1.18 type parameters: I do not believe there is any way to indicate that T may be an interface type but may not be a channel.

func Shallow[T any]() Option { ... }

Shallow could also be type parameterized, passing the type to shallow copy rather than a prototype value of that type. The limitations on expressing the constraints on T still apply.

Unlike Func, we cannot infer a type parameter for a call to Shallow, so we would need to provide functions with different names for pre- and post- generics versions of Go.

func Copy[T any](c *Copier, v T) T { ... }

We cannot parameterize the Copier.Copy method, but we could provide a Copy function that avoids the need to use a type assertion to recover the type of the new value.

Unlike the changes to Func and Shallow, this does arguably make the package API simpler to use:

b := copier.Copy(a).(T)  // need to type assert back to the type of a
b := cpy.Copy(copier, a) // no type assertion needed
@dsnet
Copy link

dsnet commented Dec 16, 2021

I think we should use type parameters for Func. This library is intended to be as performant as possible (without using unsafe). Without generics, we have to use reflect.Value.Call, which is very slow (see golang/go#43732). Even if we optimize away the allocation, it's still slower than an implementation that relies on generics.

I don't feel as strongly about making Shallow generic. If we're going to do it for Func, I guess we might as well do it for Shallow.

I think we should add copier.Copy. It doesn't replace anything existing and the benefits are clear. That said, if we're willing to break existing usages, we could do:

type Copier[T any] struct { ... }
func New[T any](...Option) *Copier[T]
func (*Copier[T]) Copy(T) T

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants