What is the difference between these two syntaxes for setting a default value for a parameter in Dart:
class Test {
Test({
int x: 2,
int y = 3,
});
}
I tried both of them and they seem to be completely identical.
They're the same. At least for now. The language tour says:
Deprecation note: Old code might use a colon (:) instead of = to set
default values of named parameters. The reason is that originally,
only : was supported for named parameters. That support might be
deprecated, so we recommend that you use = to specify default values.
So avoid using the colon in the future as it may be removed at some point.
Related
From reading this (https://www.educative.io/edpresso/what-is-a-dart-symbol) it seems that Symbols are deprecated in Dart. But I've had trouble finding an explanation for why to avoid them. This answer (Dart symbol literals) gives some explanation of what symbols are in dart, certain cases when they're commonly used. And it suggests "you shouldn't need to use symbols outside of those cases." Shouldn't need is different than shouldn't. Are they deprecated or not? If they are deprecated, why?
The docs here: (https://api.dart.dev/stable/2.12.4/dart-core/Symbol-class.html) don't mention deprecation. I couldn't find any mention of Symbols here: (https://dart.dev/guides/language/effective-dart) either for or against.
In this example the symbol seems to be working as I'd like it to:
class TrafficLight {
Symbol color;
TrafficLight(this.color);
}
void main() {
var t = TrafficLight(#red);
print(t.color == #red);
print(t.color == #green);
}
//returns:
// > true
// > false
If I have thousands of traffic lights, thousands of identical Strings are a waste of RAM. What's the common / best practice way of handling these type of situations in Dart? Enums? Creating a TrafficLightColor class?
Thanks in advance for any light you can shed on this issue.
Response to comments
#julemand101
void main() {
String a = '123';
String b = a;
a += 'foo';
print('a: $a');
print('b: $b');
}
return is:
a: 123foo b: 123
If they were pointing to the same object, I'd expect return to be
a: 123foo b: 123foo
#julemand101, You're absolutely right, my thinking was off. Thanks for the explanation.
Symbols are not deprecated. They are mainly used for reflection-like functionality like dart:mirrors, Object.noSuchMethod (the memberName and namedArguments names) and Function.apply (again the named arguments names). If you don't need those, you likely don't need to bother with symbols. You can, they're just objects, but not particularly useful objects.
(Some libraries use private symbols, like #_foo to create a library-private sentinel object, but you could also just do final _mySentinel = Object();.)
The best way to handle the traffic lights situation is enums.
You could use symbol literals (#red, #green) or string literals ("red", "green") or magic numbers (1, 2), but the only approach to creating a fixed set of values to represent a specific thing that is language and type-system supported is enums.
You can make your own enum-like class if you want to, and it'll be just as good as enums, except that you won't get a warning if you forget a case in a switch.
(If you do use string literals, you'll likely find that they are canonicalized too, so the string data won't take up more space whether they occur once or thousands of times).
C# discards prevent allocation of values not needed. Is there something similar in dart? I saw a lot of people use the underscore as if it were a discard, but using two at the same time (like this (_, _) => method() will say the variable _ is already defined.
Dart does allow you to use the same discard operator as C#. You can define a variable or final with a name of _. This works well with the rule avoid-ignoring-return-values (Dart Code Metrics) Importantly, if you name the variable with this, you will not encounter the warning unused-local-variable. However, there is another code rule called no_leading_underscores_for_local_identifiers. You can safely turn this off as long as you don't have someone in your team that has a habit of prefixing variable names with an underscore.
Ignoring the return value
Discarding the return variable
Unfortunately, it doesn't work the same way as C# because it involves an assignment, and you cannot assign two different types to it. You need to declare it as an Object?
I'm confused as to the uses of "as" keyword.
Is it a cast operator or alias operator?
I encountered the following code on the internet which looked like a cast operator:
var list = json['images'] as List;
What does this mean?
as means different things in different contexts.
It's primarily used as a type cast operator. From the Dart Language Tour:
as: Typecast (also used to specify library prefixes)
It links to an explanation of how as is also used to add a prefix to an imported library to avoid name collisions. (as was reused to do different things to avoid needing extra keywords.)
just to add the as keyword is now flagged by the linter and they prefer you to use a check like is
if (pm is Person)
pm.firstName = 'Seth';
you can read more here https://github.com/dart-lang/linter/issues/145
As the language tour says:
Use the as operator to cast an object to a particular type if and only if you are sure that the object is of that type.
Following with your example:
var list = json['images'] as List;
You would use as here to cast or convert json['images'] into a <List> object.
From another SO post (talking about explicit cast vs. as):
as ... is more like an assertion, if the values type doesn't match as causes a runtime exception.
You can also use it when importing packages. A common example is the dart:convert as JSON which then can be reached final foo = JSON.jsonDecode(baz)
It's casting, your code is similar as:
List list = json['images'];
According to the documentation for Option.Value<'T>:
Get the value of a Some option. A NullReferenceException is raised if
the option is None.
and
This function is for use by compiled F# code and should not be used
directly.
Does the last sentence imply that it's due to interop? What's the use case if so?
Otherwise it seems very strange since the whole point of the Option type is to make the possibility of undefined values explicit and encourage handling of them, which easily can be circumvented:
let none : int option = None
let value = none.Value
I imagine it is there so that
match v with
|Some(t) -> t
works - without that Value property, you wouldn't be able to get the t with any functions which are available to F# code (Note there are some DU properties which are not accesible from F# which are an alternative here). There may also be some very minor speed benifits if you know that the option is Some as you don't check it if you use value directly
I need to set a version number to be used in the AssemblyVersion attribute by several related projects.
In C# I use the following
public class Constants {
public const string Version = "1.2.3.4";
}
then it can be used as follows:
[assembly:AssemblyVersion(Constants.Version)]
What would be the equivalent construct in F#. All my attempts to come up with a binding which can be accepted as an attribute argument did not work.
Use the attribute Literal:
[<Literal>]
let version = "1.2.3.4"
[<assembly:AssemblyVersion(version)>]
Since I stepped into this trap myself I thought I'd share for anyone following.
A 'Literal' requires that the letter starts with a capital letter. This will hit you when you try to use the literal in a pattern matching construct.
Reference:
Literal attribute not working