cheekybits / genny

Elegant generics for Go
MIT License
1.71k stars 127 forks source link

Add generic Integer type #17

Open rwl opened 8 years ago

rwl commented 8 years ago

I encounter an error when using a generic type to index a slice or as the len argument to make

non-integer len argument in make([]IntType) - IntType
non-integer slice index n

My workaround has been to add a generic.Integer type, in addition to the existing generic.Number type. An alternative might be to change the generic.Number definition to:

type Number int

Another alternative is to add a // +build ignore tag to the template file, but then I think it can't be used for generic testing.

FlorianUekermann commented 7 years ago

I would like to see "Integer" added instead changing Number to int.

Integers support more operators than floats, which means "type Integer int" is necessary if you want to use those operators.

Similar to how "type Type interface{}" is useful for indicating and ensuring support for a less specific set of types than "type Number float64", the latter is useful for indicating and ensuring support for integers and floats.

pdrum commented 6 years ago

I don't understand what generic.Integer is good for. As far as I understand this type can only be replaced with int so how is it different with just using int instead of sth like generic.Integer in templates? Will you elaborate please? @rwl

rwl commented 6 years ago

IIRC, I was trying to support generating different types of int e.g. int32, int64 etc. In the end I dropped genny and just used text/template directly.

dmoles commented 5 years ago

Something like this would be useful for generating code for enum-type constants.

takeda commented 5 years ago

@pdrum generic.Number is currently an alias for float64, as mentioned in the ticket float64 can't be used as a slice index or len argument in make().

generic.Integer could be replaced with int, int8, int16, int32, int64, uint, uint8, unit16, uint32, uint64 I don't think it is any less meaningful than generic.Number, having said that I believe (I didn't test it) not using generic.* and just assigning the custom type to int would just work, so I'm thinking that creating generic.Integer would be just for completeness sake, since we already have generic.Number assigned to float64

dmoles commented 5 years ago

@takeda — So I just tried this, and naively assigning the custom type to int (or uint32 or what have you) gets you an extra type declaration that you may not want — type T generic.Type gets deleted, type T int gets transformed to type MyType int.

As a workaround, if what you want is for your templates to compile, behave well in your IDE, etc., you can put the type declarations in a separate file in the same directory. As far as I can tell this just works—which is interesting, because it suggests the whole generic.Type mechanism is unnecessary.

takeda commented 5 years ago

Ah I see, I forgot that genny removes it. In that case I agree that Integer type should be included. The workaround you gave is still a workaround and generic.* is more elegant I wouldn't call it unnecessary.

dmoles commented 5 years ago

It does make the templates more readable and more obviously templates.