0

This code snippet

class SomeWidget extends StatelessWidget {
final String aString;

SomeWidget(this.aString);

compiles without error or warning. However, this code snippet

class SomeWidget extends StatelessWidget {
final String aString;

SomeWidget(String inputString) {
    this.aString=inputString;
}

gives an error message that all final variables must be initialized and aString isn't, and how aString can't be used as a setter because it's final. Removing the final keyword eliminates the error messages.

I'm unclear what's going on here. I saw this and this SO item, but honestly I'm still struggling to understand. I think the problem, for me, stems from how I was taught my two code snippets are functionally identical.

Al C
  • 5,175
  • 6
  • 44
  • 74
  • 1
    Please explain what isn't clear. Your two linked questions have excellent explanations and you don't say where your understanding falls off. – Christopher Moore Apr 30 '21 at 21:37
  • That's a harder question than one would think but, to the extent I understand, I don't know what happens differently with the two snippets. I was taught the first is a shorter, more convenient way of writing the second. But clearly they are not identical. – Al C Apr 30 '21 at 21:49
  • The first snippet is identical to using the initializer list that is shown in your linked questions. If you're referring to being taught a language other than Dart, you shouldn't assume that anything is the same between them. They are different languages after all. – Christopher Moore Apr 30 '21 at 21:54
  • Thanks for your patience. Is it accurate to say we pretty much _must_ use the first snippet's syntax with `final` properties in Dart? – Al C Apr 30 '21 at 22:08
  • You can use the initializer list as well. Other than that, the only way to initialize a final variable is to do it on the same line on its declaration. – Christopher Moore Apr 30 '21 at 22:08

1 Answers1

1

When you declare a variable as final, this means that the state\value of this variable will not change during the life cycle of this widget.

Thus, when you declare:

final String aString;

You are telling the framework, that the value of aString, will not change, because it's final. However, when you use the setter, you are trying to do the exact opposite of what you just promised Flutter, and you are attempting to change what should be final = aka non-changeable.

Huthaifa Muayyad
  • 11,321
  • 3
  • 17
  • 49
  • So when the setter line of code is about to be executed, what's the value of `aString`? And when was it assigned the value? [And thanks for responding] – Al C Apr 30 '21 at 22:03
  • It's initialized in two ways, either when you first declare it `aString = "some value"`, or if you don't know what it'll be when writing the code, but the app will determine this later, you use your first snippet `SomeWidget(this.aString);`. Now in your code, whenever you want to instert `SomeWidget`, it'll tell you that there a required string you didn't add, and then you use `SomeWidget("userName")`. Those are the ways that the value of aString can be assigned if it's final. – Huthaifa Muayyad Apr 30 '21 at 22:17