-
Notifications
You must be signed in to change notification settings - Fork 280
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
modifies-value-receiver: add support for immutable values #1066
Comments
To me it looks like a design flaw in the given code. |
It does that - by using non-pointer receiver.
Function will do the same (receive arg of non-pointer Config type and thus gets a copy), but it'll have longer name like I agree it may looks a bit unusual, maybe even confusing - but this will gone as soon as you get used to this style. As for "design flaw" or "indeed suspicious" - I don't see how these apply. Can you explain what exactly the design flaw is and what kind of suspicions this code raises? |
Answering to all of your comments at once: this code style lacks readability and causes confusion. I'd avoid having it. It's still your and your teammates' choice, but I don't think we should change |
Hi @powerman, thank you for the proposal. |
TBH I don't see much use for this pattern except for Config-like structures. But Config structures are wide spread, so IMO it's worth support. For Config structures it's important to have both required and optional args, and ensure no references to config will exists outside after calling a New constructor (to make sure object configuration can't be modified at any moment from outside). |
Here are some examples of the pattern being used to other things than configurations (notice the cases where the receiver copy is not returned but used, after modification, to build a struct of a different type) kratos/identity/identity.go:334:2: suspicious assignment to a by-value method receiver |
While this is not an error by itself, I doubt this case worth supporting:
|
Is your feature request related to a problem? Please describe.
In some cases using immutable values can be a good style. For example, I often use
type Config struct{...}
this way, to have both (a variant of) dysfunctional options and ensure there are no references to config (or it values) outside of object using that config:This result in clean and safe code, but revive thinks it's bad:
Describe the solution you'd like
I'd like to make it possible to not trigger
modifies-value-receiver
rule in case method returns value of receiver type (or a pointer to receiver type). Examples:The reason to support references in returned value is: both
NewConfig()
andWithX()
methods may return*Config
without actually changing whole pattern. This is because copy will anyway happens when it will be used as non-reference argument (as a receiver forWithX()
or as an argument forNewThing()
. Using reference may make sense, e.g. ifConfig
is huge, or just to makeNewConfig()
looks more consistent (New
usually means return reference).I think it's safe to make
modifies-value-receiver
work this way by default, but if you unsure it can be configurable.Describe alternatives you've considered
Adding
//nolint:revive
or disablingmodifies-value-receiver
rule. First is annoying, second is unsafe.Additional context
N/A
The text was updated successfully, but these errors were encountered: