-
Notifications
You must be signed in to change notification settings - Fork 8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
refactor(context): refactor Keys
type to map[any]any
#3963
base: master
Are you sure you want to change the base?
Conversation
Signed-off-by: Flc゛ <four_leaf_clover@foxmail.com>
Keys
to map[any]any
Keys
type to map[any]any
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## master #3963 +/- ##
==========================================
- Coverage 99.21% 99.05% -0.16%
==========================================
Files 42 44 +2
Lines 3182 2751 -431
==========================================
- Hits 3157 2725 -432
+ Misses 17 15 -2
- Partials 8 11 +3
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. |
Why not just make it |
I think it's just like the It can be supported, so why not? Moreover, when the type customKey struct{}
ctx.Set(customKey{}, "xxx") package main
import (
"fmt"
"unsafe"
)
func main() {
var a int
var b string
var c struct{}
fmt.Println("a:", unsafe.Sizeof(a))
fmt.Println("b:", unsafe.Sizeof(b))
fmt.Println("c:", unsafe.Sizeof(c))
} output:
|
In Golang, maps can only have keys of types that are considered *comparable*.
This means the type needs to support the == and != operators for comparison.
which means that structs have to have nothing but *comparable* types as
their fields.
it introduces confusion when someone tries to use a key that is not
*comparable.*
*comparable *is broken as far as I am concerned, not being able to provide
a function that makes any struct *comparable* is a serious oversight and
flaw with the language.
I have ended up having to write a library that generates a unique hash of
any struct so that I can pass an array of structs I want to use as keys and
array of values and generate a map with consistent hashing of the identity
(fingerprint) of a struct as a key and the struct as the value. This allows
me to generate keys from structs and look them up in the map without having
to worry about if something I want to store in a map key is a valid key or
not.
…On Tue, May 14, 2024 at 11:24 AM Flc゛ ***@***.***> wrote:
Why not just make it comparable, or just any?
I think it's just like the key in context.WithValue(ctx, key, value).
It can be supported, so why not?
Moreover, when the key is set to struct{}, it saves more memory, ex:
type customKey struct{}
ctx.Set(customKey{}, "xxx")
—
Reply to this email directly, view it on GitHub
<#3963 (comment)>, or
unsubscribe
<https://github.com/notifications/unsubscribe-auth/AABF7754OZ67JDDN5LWVVBDZCIUERAVCNFSM6AAAAABHQT7FSWVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDCMJQGUZDINBYHA>
.
You are receiving this because you commented.Message ID:
***@***.***>
--
Jarrod Roberson
678.551.2852
|
Great reminder, I will add some single test trials. |
Signed-off-by: Flc゛ <four_leaf_clover@foxmail.com>
@jarrodhroberson It is indeed recommended to change to Some references: golang/go#51384 |
c.Set([]int{1}, 1) | ||
c.Set(func() {}, 1) | ||
c.Set(make(chan int), 1) | ||
}) | ||
} | ||
|
||
func TestContextSetGetValues(t *testing.T) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this test also check that it's possible to retrieve pointer by key? I know that it's not part of the scope of your task changes but I see that it's missing from here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is your meaning nil
?
@@ -217,6 +217,34 @@ func TestContextSetGet(t *testing.T) { | |||
|
|||
assert.Equal(t, "bar", c.MustGet("foo")) | |||
assert.Panics(t, func() { c.MustGet("no_exist") }) | |||
|
|||
// other types | |||
type key struct{} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe worth extracting into
func TestContextSetGetAnyKey(t *testing.T)
} | ||
|
||
// no comparable | ||
assert.Panics(t, func() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe worth extracting into
func TestContextSetGetPanicsWhenKeyNotComparable(t *testing.T)
Yep went over source and there's no exposed |
That is one of the inherit flaws of Go in reaction to all the insanely stupid things that other languages (JS cough cough) allow you to do. The inability to define an |
break backwards. looks not good for me. func handleTest(c *gin.Context) {
var cpKeys = make(map[string]any, len(c.Keys))
for s, a := range c.Keys {
cpKeys[s] = a
}
// ....
} |
But gin.Context is an implementation of context.Context. And it is a broken implementation, because keys should be any, like in the original context.Context. And so this change is more important, because it fixes this bug. |
Keys
to support more types.The first step in solving #1123 (comment)