-
Notifications
You must be signed in to change notification settings - Fork 1.7k
proposal: avoid_var_declarations
#58608
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
Comments
Can you explain a bit more why this lint rule would allow |
Sure, I think it boils down to "intention". If you declare a field as var a = '5'; // String, not to be confused with an int
var b = 5 + 3 / 1; // double or int? It's a double
var c = 8;
double d = 8;
... EdgeInsets.all(c) // Error
... EdgeInsets.all(d) // Fine Bottom-line is I could get rid of If you dislike There are more examples in the lint description and lots of tested examples that cover also locals but I can add some of them for you above. |
Thanks for the details. I still don't see why the current lint rules (the overlaps you mention) do not cover your needs.
This is covered by
This is covered by Are you saying you want explicit types, except in the case of final and const variables, in which case the preference for self-documentation and higher readability are no longer important? Why would a variable being final or const change whether you want readability, self-documentation, or inference? |
Yes, that's all correct. Maybe we should call the rule But would a subset of The reason I find adding the type of final variables redundant is that most of the time, you create or reference class instances as:
and I don't want to add another Maybe we should have a rule where types only need to get specified when the name isn't already part of the expression or equals the name of the constructor. 🤔 |
I think it would be great if we could unify two rather disjoint subcommunities in the Dart community: The ones who enable The point is, as mentioned already in this issue, that declarations like So it might be useful if we could make these lints less aggressive, such that everybody can have declared types just when they think it is useful (OK, nearly so ;-). We would need to do something like the following:
A rather strict style could be maintained by enabling both lints: The declared type would then be included, essentially, if and only if the type is not trivial. The discussion about what makes a type trivial has been taken several times. For instance, I proposed some ideas here, and a broader discussion about this concept can be found in Avoid unnecessary type annotations. I'm not so sure about the distinction between import 'whatever needed';
void main() {
final x = foo(bar()); // `foo` and `bar` could be generic.
final y = baz(x); // Now we depend on two layers of implicit typing.
...
y.qux('Hello!'); // Error, `TheTypeOfY<With,Several,Arguments>.qux` does not accept a string!
} So perhaps it would be useful to just check for trivial types, and in particular to treat mutable and immutable variables the same? |
This request seems to be for a very bespoke style. As noted, the suggested rule overlaps with We cannot accept all possible lint rules into the linter codebase, since it is maintained by a small team, and each rule does add a maintenance effort. I think this rule is too far from typical coding styles to be considered for the linter codebase. |
avoid_var_declarations
Description
Avoid using
var
altogether. Instead, declare a variable using its explicit type,final
orconst
.Details
Declaring a variable using its explicit type is slightly more verbose but improves readability, adds self-documentation (also in terms of whether the variable is nullable or not) and makes sure that you are not dependant on compiler-inferred types. Declaring variables as final is good practice because it helps avoiding accidental reassignments and allows the compiler to do optimization.
Kind
Style.
Good Examples
Bad Examples
Discussion
I've personally never used
var
in any of my projects, not a single time. If there is a rule such asunnecessary_final
(which I feel rather negative about), I think the opposite should also exist so it can be set as a project standard in a collaborative context.To my knowledge, the proposal:
unnecessary_final
andomit_local_variable_types
andalways_specify_types
,prefer_final_fields
,prefer_final_locals
andprefer_final_in_for_each
.Despite numerous overlaps with existing rules, I'm still missing the one that hits the nail on the head, especially since the other rules are somewhat differently nuanced. For example, if I'd be fine with not having
always_specify_types
activated (because I'm absolutely okay withfinal _controller = TextEditingController();
vs.final TextEditingController _controller = TextEditingController();
),var i = 0
would also be allowed if it is reassigned while all the other rules are turned on.I understand that
var
is very popular among Flutter/Dart devs that follow a more practical approach. I also wouldn't add it to the standard library of lint rules, especially not for beginners. But I would definitely count myself to those who'd always have it activated if it exists.Further reads:
https://github.com/flutter/flutter/wiki/Style-guide-for-Flutter-repo#avoid-using-var-and-dynamic
https://dart.dev/guides/language/effective-dart/usage#do-follow-a-consistent-rule-for-var-and-final-on-local-variables
https://stackoverflow.com/questions/61183907/should-i-give-type
https://stackoverflow.com/questions/66836046/difference-between-var-and-other-more-specific-types-in-dart
Discussion checklist
The text was updated successfully, but these errors were encountered: