In Dart, when two imported libraries both declare a class named `Element`, how do `import ... as`, `show` and `hide` resolve the clash?
answer
- clash only errors where used
- prefix gives a namespace
- show is an allow-list
- hide is a deny-list
- extensions filtered by extension name
basics
~20 sBind one library to a prefix with as, so its names are reached as lib2.Element, or narrow an import with show (only the listed names) or hide (everything except the listed names). Unresolved clashes are errors only where the name is used.
solid answer
~30 sTwo imports that both expose `Element` are fine until code *references* `Element`; then the name is ambiguous and the analyzer reports a compile-time error. You fix it in the import list: `import 'package:lib2/lib2.dart' as lib2;` puts lib2's names behind a prefix (`lib2.Element`), while `show Element` imports only the listed names and `hide Element` imports everything except them. Prefixes and combinators combine (`as p show join`). A declaration in your own library shadows imported names, so a local `Element` needs no combinator. Extensions are filtered by the extension's name, so a `show` list that omits an extension also drops its methods.
code
dart · 10 linesimport 'dart:math' as math;
import 'package:path/path.dart' as p show join, basename;
import 'package:flutter/material.dart' hide Badge;
import 'package:my_badges/my_badges.dart' show Badge;
String avatarPath(String dir, String user) => p.join(dir, '$user.png');
double clampRatio(double r) => math.min(1, math.max(0, r));
Widget unread(int n) => Badge(count: n); // from my_badges, not Materialgo deeper
Know the three tools: as for a prefix, show for an allow-list, hide for a deny-list, and that the clash errors only where the name is used.
Explain that local declarations shadow imports, that combinators and prefixes combine, and that extensions are filtered by their extension name.
Show judgment on import hygiene: prefixes for generic utility libraries, show lists to document dependencies, and hide only for single collisions in large libraries.
Frame import style as a team convention enforced by lints, trading explicit call sites against noisy import lists across a large codebase.
## What an import actually brings in In Dart, every file is a **library**, and an `import` directive makes the public namespace of another library available in yours. The only required part is the **URI**: `dart:` for platform libraries (`dart:async`, `dart:math`), `package:` for libraries in a package that pub resolved, or a relative path for a file in the same package. Without anything else, every public name of the imported library joins your top-level scope. That is convenient until two libraries export the same name. Dart does **not** fail at the import lines: the conflict becomes a compile-time error only at the point where code **references** the ambiguous name. Two things resolve it: - a **prefix** (`as`), which moves the whole library behind a namespace; - a **combinator** (`show` or `hide`), which filters which names come in at all. ## Prefixes with `as` `import 'package:lib2/lib2.dart' as lib2;` binds lib2's names to the prefix: you write `lib2.Element`, `lib2.parse()`. The unprefixed names are **not** also imported. Prefixes are the idiomatic answer for libraries with generic top-level names: `package:path` is conventionally imported `as p` so `p.join(...)` never collides with anything, and `dart:math` is often imported `as math`. The `library_prefixes` lint in `package:lints`' recommended set expects prefixes in `lower_case_with_underscores`. Since **Dart 3.7** a prefix spelled `_` is a **wildcard**: it binds no name, but the library's non-private **extensions** still apply. That is a way to import a library purely for its extension methods. ## Combinators: `show` and `hide` | Form | What enters scope | |---|---| | `import 'a.dart';` | every public name of `a.dart` | | `import 'a.dart' show foo, Bar;` | only `foo` and `Bar` | | `import 'a.dart' hide foo;` | every public name except `foo` | | `import 'a.dart' as a show foo;` | only `foo`, reached as `a.foo` | `show` is an **allow-list** and documents exactly what a file depends on; `hide` is a **deny-list**, handy when one name collides and you want the rest of a large library such as `package:flutter/material.dart`. Private names (a leading `_`) are never importable, so they never appear in either list. ## Extensions follow the same rules Extension methods travel with their **extension's name**. If two libraries both add `parseInt()` to `String` through extensions named `NumberParsing` and `NumberParsing2`, `hide NumberParsing2` removes one of them. A `show` list that forgets to name an extension silently drops its methods, a frequent cause of "the method isn't defined for the type" errors after someone tightened an import. ## Shadowing and how to choose A declaration in **your own library** shadows an imported one of the same name, so a local `class Element` does not need a combinator; only two *imported* declarations collide. Choosing a fix: 1. If you need both types in the same file, prefix at least one library. 2. If you need one name from a small utility library, use `show`. 3. If you need almost all of a large library except one clashing name, use `hide`. 4. If the clash is between extension members, `hide` the extension by name or apply it explicitly, `NumberParsing('42').parseInt()`. Prefixes keep call sites explicit at the cost of noise; `show` lists keep dependencies explicit at the cost of editing the import each time you use one more name.
- In Dart, after tightening an import to `show Parser`, calls like `'42'.parseInt()` stop compiling. Why?`parseInt()` comes from an extension declared in that library, and extensions are filtered by the extension's own name. `show Parser` imports only `Parser`, so the extension is not in scope. Add the extension name to the `show` list, or drop the combinator.
- In Dart, does a prefixed import also make its names available without the prefix?No. `import 'x.dart' as x;` introduces only the prefix; every name must be written `x.Name`. If you want both, you would need a second, unprefixed import of the same URI, which is legal but rarely a good idea.
saying these in an interview costs you the question
- Two imports exporting the same name fail at the import lines
- The import written last silently wins a name clash
- A prefixed import also exposes its names unprefixed
- hide can bring a library's private _names into scope
- show only filters classes; extension methods always come along