How to distinguish the class member from global variable with the same name in Dart?

21 views Asked by At

I am trying the following code:

String user() {
  return "";
}

class Foo {
  String user;
  Foo() : user = user(); // <= error here
}

void main() {}

But it doesn't work because of name ambuguity.

I can move globals to another module and import as globals to avoid it.

Is there any other way?

1

There are 1 answers

0
lrn On BEST ANSWER

The Dart lexical lookup, used to give meaning to plain identifiers, stop at the first scope level which contains a member with that name. Qualified identifiers, the bar in foo.bar, are not looked up lexically, so they do not have the same issue.

You need to provide a way to access the outer name using either another plain name, or using a qualified name.

The other plain name is the easier way:

String user() {
  return "";
}

String _user() => user(); // Add redirect with other name
// or `const _user = user;` to create a tear-off.

class Foo {
  String user;
  Foo() : user = _user(); // <= No error now
}
void main() {}

Adding a prefix for a top-level name is slightly harder. If it's an imported name, also import the same library with a prefix:

import "other.dart"; // provides `user`
import "other.dart" as other; // access also as `other.user`
...
  : user = other.user() ...

If the member is declared in the same library, then the solution is the same: Import the library with a prefix. It just feels a little more weird to import the current library into itself, but it's perfectly fine and valid Dart.

library my_library;
import "my_library.dart" as self;
String user() => ...
// ...
   ...: user = self.user() ...

It's only top-level names that have this issue. Static or instance members can be accessed with a qualified identifier using ClassName.staticMember or this.instanceMember, without needing to introduce a new prefix name.