How to cast static variable as a constant and use it to pass to class constructor that expecting final - flutter

Got an error for following code
Cannot invoke a non-'const' constructor where a const expression is expected.
Try using a constructor or factory that is 'const'.
static const MyClass darkerText = MyClass(param);
Understood that using static in this instance might be inappropriate. Just wanted to look if there is any possible way to do so.
class MyClass {
final int total;
MyClass(total);
}
class Test {
static int param = 10;
static const MyClass darkerText = MyClass(param);
}
main() {
new Test();
}

You seem to have misunderstood the point of const and final. const is for values that are known at compile time, so in your case this is possible, though somewhat pointless, if all your values are compile time constants:
class MyClass {
final int total;
const MyClass(this.total);
}
class Test {
static const int param = 10;
static const MyClass darkerText = MyClass(param);
}
main() {
new Test();
}
What is more normal is to use final variables, which can be set during the program's lifecycle but don't change after being set, in which case you would use something like this:
class MyClass {
final int total;
MyClass(this.total);
}
class Test {
static int param = 10;
static final MyClass darkerText = MyClass(param);
}
main() {
new Test();
}

You can copy paste run full code in DartPad
You need to use this.total and remove const keyword of darkerText
class MyClass {
final int total;
MyClass(this.total);
}
class Test {
static int param = 10;
static MyClass darkerText = MyClass(param);
}
main() {
print(Test.darkerText.total);
}

As the error says, your MyClass is a non-const constructor.Make it const:
class MyClass {
final int total;
const MyClass(this.total);
}
class Test {
static const int param = 10;
static const MyClass darkerText = MyClass(param);
}
void main() {
new Test();
}

Related

Dart using variable to hold set of constructor parameters, to be used in multiple constructors?

is there a way to use some variable or any holder to store constructor parameters,
to be able to pass them to multiple constructors without repeating the values?
I think its possible if the constructor has only positional parameters (no named parameters).
var parametersHolder={
named1: "str",
named2: "lorem",
};
// normal usage
constructorA(named1: "str", named2: "lorem");
constructorB(named2: "lorem",named1: "str" );
my question is how to do the following in dart:
constructorA(parametersHolder);
constructorB(parametersHolder);
so is that achievable ?
Thanks
If you really want, you could use Function.apply with a constructor tear-off:
class Foo {
String named1;
String named2;
Foo({required this.named1, required this.named2});
#override
String toString() => 'Foo: $named1 $named2';
}
void main() {
var namedArguments = {
#named1: 'str',
#named2: 'lorem',
};
var foo = Function.apply(Foo.new, null, namedArguments) as Foo;
print(foo); // Prints: Foo: str lorem
}
Note that doing this sacrifices compile-time type-safety.
You can define a class to hold your parameters like this:
class MyClass{
late final int myInt;
late final String myString;
MyClass.firstConstructor(MyClassParams params){
this.myInt = params.myInt;
this.myString = params.myString;
}
MyClass.secondConstructor(MyClassParams params){
this.myInt = params.myInt;
this.myString = params.myString;
}
}
class MyClassParams{
final int myInt;
final String myString;
const MyClassParams(this.myInt, this.myString);
}

How to set a function parameter's default value as an object of a class which extends an abstract class?

Let's say I have several classes which extend an abstract class. Now I want to pass a default value to a function argument, where the type of the argument is the abstract class. Dart expects a const value, and I couldn't create a const constructor for an abstract class. How can I pass a default value of the abstract class?
Sample code is as following:
class Main {
late A objOfA;
Main({ A nObjOfA = const B() }); // <===== Error here
}
abstract class A {
abstract String name;
abstract int id;
}
class B extends A {
#override
String name = "B";
#override
int id = 1;
}
class C extends A {
#override
String name = "C";
#override
int id = 1;
}
Here, how can I pass a default value of nObjOfA in the constructor of Main?
Dart expects a const value, and I couldn't create a const constructor for an abstract class.
There is no rule that you cannot create a const constructor for an abstract class. Abstract classes can have constructors; you just can't call them directly to instantiate an abstract class. The following code is legal:
class Main {
A objOfA;
Main({this.objOfA = const B()});
}
abstract class A {
const A();
abstract final String name;
abstract final int id;
}
class B extends A {
const B();
#override
final String name = "B";
#override
final int id = 1;
}
class C extends A {
#override
String name = "C";
#override
int id = 1;
}
Note that I needed to add final qualifiers since const objects must be immutable. (Unrelated, but I also fixed the inappropriate use of the late keyword.)
In general, there will be cases where you cannot create a const constructor. If you want to use an instance of that type as a default argument in such cases, you can use null as a default value and assign a non-const value later.

Is there a quick way to create a new instance of a Dart class from an existing object?

Basically wondering if there is a quick way other than creating a method to create a new class instance from itself so the example below would print 9, not 15.
void main() {
final classOne = SomeClass(mutableString: 'Hello', mutableInt: 9);
final classTwo = classOne;
classTwo.mutableInt = 15;
print(classOne.mutableInt);
}
class SomeClass {
SomeClass({required this.mutableString, required this.mutableInt});
String mutableString;
int mutableInt;
}
Thanks
You can add a method in the class which retuns the same object.
For example :
I am ading copyWith method in SomeClass
class SomeClass {
SomeClass({required this.mutableString, required this.mutableInt});
String mutableString;
int mutableInt;
SomeClass copyWith({int? mutableInt}) {
return SomeClass(
mutableString: this.mutableString,
mutableInt: mutableInt ?? this.mutableInt,
);
}
}
Now you can use the method as :
void main() {
final classOne = SomeClass(mutableString: 'Hello', mutableInt: 9);
final classTwo = classOne.copyWith(mutableInt:15);;
print(classOne.mutableInt);
}
#anoncgain solution is correct up-to an extent.
You can also do the same as
class SomeClass {
//...other code ....
String? mutableString; //make your params nullable
int? mutableInt;
//declare a named constructor to copp the existing object value.
SomeClass.copy(SomeClass object){
mutableString = object.mutableString;
mutableInt = object.mutableInt;
}
}
Then you can use it as
final classTwo = SomeClass.copy(classOne);
//it will copy the values to the newly created object
//rather then storing the reference of the object

How to override a Dart method on instantiation? [duplicate]

Is there way to overriding method in Dart like JAVA, for example:
public class A {
public void handleLoad() {
}
}
And when overriding:
A a = new A() {
#Override
public void handleLoad() {
// do some code
}
};
No, Dart does not have anonymous classes. You have to create a class that extends A and instantiate it.
No but it much less useful in Dart because you can just reassign function:
typedef void PrintMsg(msg);
class Printer {
PrintMsg foo = (m) => print(m);
}
main() {
Printer p = new Printer()
..foo('Hello') // Hello
..foo = ((String msg) => print(msg.toUpperCase()))
..foo('Hello'); //HELLO
}
However you will need some extra boilerplate to access instance.
Use type Function:
class A {
final Function h
A(this.h);
void handleLoad(String loadResult) { h(loadResult); }
}
Or
class A {
final Function handleLoad;
A(this.handleLoad);
}
A a = new A((String loadResult){
//do smth.
});

Debug Partial Mock in JMockit

Using JMockit 0.999.4 and JDK6, is it possible to debug into a partially mocked class?
Consider the following test:
#Test
public void testClass() {
SampleClass cls = new SampleClass();
System.out.println(cls.getStaticInt());
cls.setVal(25);
System.out.println(cls.getVal());
}
static class SampleClass {
static int staticInt = 5;
private int val;
{
staticInt = 10;
}
public int getStaticInt() {
System.out.println("Returning static int and adding a line for debugging");
return staticInt;
}
public void setVal(int num) {
System.out.println("Setting val and adding a line for debugging");
this.val = num;
}
public int getVal() {
System.out.println("Returning val and adding a line for debugging");
return this.val;
}
}
Placing a breakpoint on each of the sysout lines in SampleClass and debug "Step Over" in Eclipse will enter the SampleClass methods.
Consider the following which will prevent the static initializer from setting staticInt to a value of 10.
#Test
public void testClass(#Mocked(methods = "$clinit") SampleClass cls) {
System.out.println(cls.getStaticInt());
cls.setVal(25);
System.out.println(cls.getVal());
}
static class SampleClass {
static int staticInt = 5;
private int val;
{
staticInt = 10;
}
public int getStaticInt() {
System.out.println("Returning static int and adding a line for debugging");
return staticInt;
}
public void setVal(int num) {
System.out.println("Setting val and adding a line for debugging");
this.val = num;
}
public int getVal() {
System.out.println("Returning val and adding a line for debugging");
return this.val;
}
}
However, this code will not debug into the methods in SampleClass.
Yes, I have tried the -javaagent property.
Answered by Rogerio in the JMockit Google's discussion group.
The JVM discards the breakpoints set on a class after it is redefined
(which JMockit does whenever a class is mocked).
To reset the breakpoints, stop the debugger at the test method, just
before it enters the code under test. That is, set a breakpoint in the
test method, on the line which calls into "SampleClass" in this
example.