The instance member 'a' can't be accessed in an initializer [duplicate] - flutter

In Dart, is there a difference in assigning values right away vs in constructor like in Java?
class Example {
int x = 3;
}
vs
class Example {
int x;
Example() {
x = 3;
}
}
I ask because when I was using Flutter and tried to assign a Function that uses setState to a variable, it was not possible with the former method but possible with the latter.

In your trivial case, it doesn't matter.
In general, you can initialize instance variables in a few ways:
Inline (field initializers)
class Example1 {
T x = value;
}
Advantages:
Direct, concise.
Member will be initialized in all constructors.
Can be used to initialize final or non-nullable members.
Member is initialized before invoking base class constructors, which is important when the base class constructor calls member functions that are overridden by the derived class.
Disadvantages:
Cannot depend on construction arguments.
Usually cannot depend on this since the initialization occurs before this becomes valid (i.e., cannot depend on other instance members). (An exception is if the member is initialized lazily by declaring it late. This requires the null-safety feature to be enabled.)
Initializer list
class Example2 {
T x;
Example2() : x = value;
}
Advantages:
Can be used to initialize final or non-nullable members.
Member is initialized before invoking base class constructors, which is important when the base class constructor calls member functions that are overridden by the derived class.
Can utilize construction arguments.
The initialized variable always refers to a member variable, never to a constructor parameter.
Disadvantages:
If the class has multiple constructors, initialization would need to be duplicated, or constructors should redirect to a common constructor.
Cannot depend on this since the initialization occurs before this becomes valid (i.e., cannot depend on other instance members).
Can initialize only members of the enclosing class. Because initializer lists are executed before invoking base class constructors, they cannot set base class members.
Constructor body
class Example3 {
T x;
Example3() {
x = value;
}
}
Advantages:
Can utilize construction arguments.
Can be used to perform more complicated initialization, such as cases where the member cannot be initialized via a single expression.
Can use this (i.e., can use other instance members).
Can be used to set base class members.
Disadvantages:
Cannot be used to initialize non-late final nor non-nullable members.
If the class has multiple constructors, initialization would need to be duplicated or initialization code would need to be refactored out (such as, but not limited to, redirecting to a common constructor).
Member is initialized after invoking base class constructors.
If the constructor has a parameter that shadows a member variable, it's easy to accidentally refer to the parameter instead of the member. (See https://github.com/dart-lang/linter/issues/2552 for details.)
There probably are some points I'm forgetting, but I think that should cover the main ones.
Direct, inline initialization occurs first, then initialization lists, then constructor bodies. Also see Difference between assigning the values in parameter list and initialiser list, which explains why this becomes valid only for the later stages of object initialization.
As an example where it matters where members are initialized:
class Base {
Base() {
doSomething();
}
void doSomething() {}
}
class DerivedEarly extends Base {
int? x;
DerivedEarly() : x = 42;
#override
void doSomething() => print(x);
}
class DerivedLate extends Base {
int? x;
DerivedLate() {
x = 42;
}
#override
void doSomething() => print(x);
}
void main() {
DerivedEarly(); // Prints: 42
DerivedLate(); // Prints: null
}

Related

Dart - Limit generic constrained type to sub type

i am currently working with Flutter/Dart. I want to implement a generic helper class, which puts a received input value into a generic wrapper, depending on the type.
Here the example code:
class ClassA {}
class ClassB<T> {
ClassB(this.t);
final T t;
}
class ClassC<T extends ClassA? {
ClassC(this.t);
final T t;
}
class ClassD<T> {
ClassD(this.t);
final T t;
Object getWrapper(){
final t = this.t;
return T == ClassA?
? ClassC<T>(t) //<--fails
: ClassB<T>(t);
}
}
Produces:
'T' doesn't conform to the bound 'ClassA?' of the type parameter 'T'.
ClassD is the helper which produces the wrappers. For the wrapper ClassB there is no isdue, but i could not get it to work for the wrapper ClassC. As it constrains its generic type it conflicts with the generic type of the wrapper itself, although i also included a type check there to limit the type to the constrained one.
I am wondering why this won't work and how it could be adjusted to make it work.
I tried to add a type check and adjusted it in various ways like
T == ClassA
or
T is ClassA
also including the local variable t
T == ClassA && t is ClassA

If define an instance variable which type is the defining class self

What will happen if I define a class like below code with Swift, the complier doesn't give any errors:
class Test {
var test = Test()
}
Nothing strange happens.
It is perfectly legal for a class to hold a reference to an instance of the same class (i.e.: liked lists, trees, etc.)

How to cast an object with a generic type

I have this small code snippet:
class A<T> {
A(this.a);
final T a;
}
void main() {
final a = A(true);
print(a);
print(a as A<bool>);
final b = A<Object>(true);
print(b);
print(b as A<bool>);
}
I'm receiving the object b from a library/API which is a A<Object> (and I don't have control over it), but I know it is actually a A<bool> in my specific case. I'm trying to cast it to A<bool> (as in my code snippet with b). But I get an error saying that A<Object> is not a subtype of A<bool>.
Here are the logs from the code snippet pasted above:
Instance of 'A<bool>'
Instance of 'A<bool>'
Instance of 'A<Object>'
Uncaught Error: TypeError: Instance of 'A<Object>': type 'A<Object>' is not a subtype of type 'A<bool>'
How can I cast b (a A<Object>) into a A<bool>?
How can I cast b (a A<Object>) into a A<bool>?
You can't. They're not the same type.
b was constructed as an A<Object>, so its runtime type is A<Object>, regardless of whether b.a happens to be referring to a bool. A cast with as changes the static (known to the compiler) type of an object, but you cannot change an object's runtime type. If you want an object with a different runtime type, you must construct a separate object.
Let's consider a slightly different example:
class C<T> {
T value;
C(this.value);
}
C<T> is the same thing as A<T> except that its member is not final. If casting an object with a runtime type of C<Object> to C<bool> were allowed, then we could have the following:
final c = C<Object>(true);
final casted = c as C<bool>; // Should this be allowed?
c.value = 'Hello world!'; // Legal since `c.value` is of type `Object`.
bool someBool = casted.value; // ???
Arguably the case for casting A is different; A's member is final and therefore wouldn't lead to the above scenario. However, I'd expect that that kind of exception would add a lot of complexity and possibly could make things even more confusing.
Also see: https://stackoverflow.com/a/67223011/
The following code can cast it. dont know if it works in your case.
var c = A<bool>(b.a as bool);
/// OR
extension Cast on A<Object> {
A<bool> cast() => A<bool>(a as bool);
}

Using final for subclass in swift

I have two class A , B. B is the subclass of A. Can I use final for class B. I want to reduce the dynamic dispatch. What if there is method in class b that is overriding the class A method . How method dispatching will work?
class A {
///
}
final class B : Class A {
}
Yes, You can
Swift gives us a final keyword just for this purpose: when you declare a class as being final, no other class can inherit from it. This means they can’t override your methods in order to change your behavior – they need to use your class the way it was written.
The final keyword is a restriction on a class, method, or property that indicates that the declaration cannot be overridden. This allows the compiler to safely elide dynamic dispatch indirection.
So you can use it.

Haxe java.lang.Object Equivalent

Haxe allows class inheritance hierarchies
class Honda extends Car {
...
}
is there a common inheritance hierarchy root for all objects? I have a generic container class that could contain any object and I want to be able to declare
var _contents:Object; //Any class instance in _contents
How can I do this?
You can also use {} as a type, which will accept class instances as well as anonymous objects :
var _contents:{};
We also have Dynamic, which basically means "anything" (not only objects, but also primitives like Bool, Int, etc).
If your class is a generic container, you may want to type its content, though, using type parameters:
class Container<T> {
var _contents:T;
public function new(contents:T):Void {
_contents = contents;
}
}
And then:
var arrayContainer = new Container([]);
var stuffContainer = new Container({foo:"bar"});
var classContainer = new Container( new Stuff() );
The inheritance root for classes is Class<T> so the following should work:
var _contents:Class<T>;
However, to store an Enum, you would have to use Enum<T> instead.
From the manual:
There is a special type in Haxe which is compatible with all classes:
Define: Class<T>
This type is compatible with all class types which means that all classes (not their instances) can be assigned to it. At compile-time, Class<T> is the common base type of all class types. However, this relation is not reflected in generated code.
This type is useful when an API requires a value to be a class, but not a specific one. This applies to several methods of the Haxe reflection API.