NOTE: This is not to be merged until generics make it into mainline go, and even then care will have to be taken with versioning so clients without generics will still be able to compile.
luke@Lukes-MacBook-Air go-cache % ~/goroot/bin/go tool go2go run cache.go2
Hello world
Caveats:
This is embarrassing but I couldn't figure out how to run this code directly without temporarily changing the package name to main. I tried to put it into ~/go2/src and import it into a client project, but it complained about not being able to reference private field .cache, see caveat 2. Maybe there's a different way to do it, or maybe caveat 2 has to be addressed first.
I'm not sure if this is the go2go tool, but for some reason the go2 code needed to address the .cache field of Cache directly. For example, in my small client implementation at the bottom of cache.go2, if you replace c.cache.Set with the appropriate c.Set you get this compilation error:
cache.go2:1146:2: type *Cache(string) of c does not match *cache(T) (cannot infer T)
In general, I don't quite understand how all the methods here are able to be about cache and not Cache, I guess there's some sort of magic since cache is the only value in the struct? However it happens, it looks like that's not working in go2.
I needed to define ItemMap in lieu of map[string]Item due to a limitation in complex inline types in generic go. I asked about this in the go slack (https://gophers.slack.com/archives/C88U9BFDZ/p1598134017011500) and was told that this is the only option.
The runtime.SetFinalizer didn't work as is, perhaps the same issue as caveat 2, maybe some other thing, I pulled it out for now.
I commented out all the Increment code; I'm not sure the best approach here. Maybe some sort of IncrementableCache, but that seems to defeat the purpose of generic code :) I wonder if there's a way to define these methods and have client code fail to compile if they try to call Increment() on a cache they set up with e.g. strings or something?
I haven't touched the tests or the sharded file, other than to rename them to .go2 which is required by the go2go tool.
NOTE: This is not to be merged until generics make it into mainline go, and even then care will have to be taken with versioning so clients without generics will still be able to compile.
I wanted to test out the generics proposal for go (https://go.googlesource.com/proposal/+/refs/heads/master/design/go2draft-contracts.md), and I thought a good exercise would be to try to convert some code into generic code.
Below is a "working" example, which can be run like this (following instructions here: https://go.googlesource.com/go/+/refs/heads/dev.go2go/README.go2go.md)
Caveats:
main
. I tried to put it into ~/go2/src and import it into a client project, but it complained about not being able to reference private field.cache
, see caveat 2. Maybe there's a different way to do it, or maybe caveat 2 has to be addressed first..cache
field ofCache
directly. For example, in my small client implementation at the bottom of cache.go2, if you replacec.cache.Set
with the appropriatec.Set
you get this compilation error:In general, I don't quite understand how all the methods here are able to be about
cache
and notCache
, I guess there's some sort of magic sincecache
is the only value in the struct? However it happens, it looks like that's not working in go2.ItemMap
in lieu ofmap[string]Item
due to a limitation in complex inline types in generic go. I asked about this in the go slack (https://gophers.slack.com/archives/C88U9BFDZ/p1598134017011500) and was told that this is the only option.runtime.SetFinalizer
didn't work as is, perhaps the same issue as caveat 2, maybe some other thing, I pulled it out for now.Increment
code; I'm not sure the best approach here. Maybe some sort ofIncrementableCache
, but that seems to defeat the purpose of generic code :) I wonder if there's a way to define these methods and have client code fail to compile if they try to call Increment() on a cache they set up with e.g. strings or something?sharded
file, other than to rename them to.go2
which is required by the go2go tool.