Declarations
Imports — uses and use
Bring a namespace's names into scope in bulk with uses, or one name at a time with use ... as ....
since 0.1.0-alpha.1linuxwindowswasm
Description
Namespace members are normally reached with a qualified path such as Shop::price. Two statements
import names so that the path can be dropped:
uses NS; // import ALL of NS's names into the enclosing scope
uses A::B; // a nested path works the same way
use NS::name; // import ONE name: a value, function, class or namespace
use NS::name as alias; // import it under another name
use A::B; // import a nested namespace itself; B::f() then works
uses imports every name of a namespace at once. use imports a single name, of any kind, and the
optional as renames it, which avoids collisions with names you already have.
Imports are resolved entirely at compile time. An alias is another name for the same declaration, not a copy, so assigning to an imported variable through its alias assigns the original variable.
Importing one name, a whole namespace, and a nested namespace
namespace Shop {
int tax = 8;
int price(int base) => base + base * tax / 100;
class Cart {
int items = 3;
}
namespace Pay {
string method() => "card";
}
}
uses Shop;
use Shop::price as shopPrice;
use Shop::Pay;
console.writeln(shopPrice(100));
console.writeln(Pay::method());
console.writeln(tax);
console.writeln(Cart().items);
108
card
8
3
Rules
- An import is a declaration in the scope where it is written, and that scope is whatever block, function body or file contains it. An import written at the top of a file is visible in that file only, not in the rest of the program.
- Imports are hoisted: an import is visible throughout its whole scope, including statements that come before it.
- A declaration in a scope hides an imported name of the same spelling that arrives from a wider
scope or from the same scope. In particular, a nearer
usehides a fartheruse, and a function declared in a scope hides an import of the same name in that scope. - Within one scope,
usebeatsuses: a name imported byusewins over the same name brought in byuses. - An alias names the same declaration, so writing through an alias writes the original variable.
Writing through the alias of a
constvariable is the same compile error as writing theconstdirectly. usecan import any kind of declaration: a variable, a function, a class, an interface or a nested namespace.useof a class or interface type can also activate a dependency-injection binding that the type's namespace exports; seelang.bind-activation.usesnever activates a binding.
Examples
A use in a nearer scope wins over a uses in the same scope, and an import in a function body is
visible only inside that function:
Specific beats bulk, and scoping
namespace Shop {
int price(int base) => base + 1;
}
namespace Other {
int price(int base) => base * 2;
}
uses Shop;
void bulk() {
uses Other;
use Shop::price;
console.writeln(price(100));
}
void nearer() {
use Other::price;
console.writeln(price(100));
}
bulk();
nearer();
console.writeln(price(100));
101
200
101
In bulk, uses Other and use Shop::price both supply price, and the specific use wins.
In nearer, the function's own use hides the file-level uses Shop. Outside both functions only
uses Shop is in scope.
An alias is the same variable under another name:
Writing through an alias
namespace Cfg {
int hits = 0;
}
use Cfg::hits as h;
h = 50;
h += 1;
console.writeln(Cfg::hits);
51
An import is visible in its own file only:
File scope of an import
// file a.lev
namespace NS { int v() => 7; }
uses NS;
int fromA() => v(); // fine: the import is in this file
// file b.lev
console.writeln(fromA());
console.writeln(v()); // error: unknown function 'v'; b.lev has no import
Notes
An import is a compile-time rename, so it costs nothing at run time.
See also
- Namespaces — Group declarations under a name, reopen a namespace to add to it, nest namespaces, and reach members with
::.